diff options
426 files changed, 14022 insertions, 9292 deletions
diff --git a/.bzrignore b/.bzrignore index 68e8120fae0..1d0184fb0f5 100644 --- a/.bzrignore +++ b/.bzrignore @@ -4,6 +4,7 @@ *.bb *.bbg *.bin +*.cmake *.core *.d *.da @@ -17,6 +18,7 @@ *.map *.o *.obj +*.old *.pch *.pdb *.reject @@ -25,11 +27,21 @@ *.so *.so.* *.spec +*.user +*.vcproj +*/*.dir/* */*_pure_*warnings */.pure +*/debug/* +*/release/* *~ .*.swp +./CMakeCache.txt +./MySql.ncb +./MySql.sln +./MySql.suo ./README.build-files +./cmakecache.txt ./config.h ./copy_mysql_files.bat ./fix-project-files @@ -65,6 +77,7 @@ BitKeeper/post-commit-manual BitKeeper/tmp/* BitKeeper/tmp/bkr3sAHD BitKeeper/tmp/gone +CMakeFiles/* COPYING COPYING.LIB Docs/#manual.texi# @@ -671,6 +684,7 @@ mysql-test/*.ds? mysql-test/*.vcproj mysql-test/gmon.out mysql-test/install_test_db +mysql-test/mtr mysql-test/mysql-test-run mysql-test/mysql-test-run.log mysql-test/mysql_test_run_new @@ -913,6 +927,7 @@ ndb/src/common/mgmcommon/printConfig/*.d ndb/src/common/portlib/libportlib.dsp ndb/src/common/transporter/libtransporter.dsp ndb/src/common/util/libgeneral.dsp +ndb/src/common/util/testBitmask.cpp ndb/src/cw/cpcd/ndb_cpcd ndb/src/dummy.cpp ndb/src/kernel/blocks/backup/libbackup.dsp @@ -1138,6 +1153,7 @@ sql/*.ds? sql/*.vcproj sql/.gdbinit sql/client.c +sql/f.c sql/gen_lex_hash sql/gmon.out sql/lex_hash.h @@ -1192,6 +1208,7 @@ strings/ctype_autoconf.c strings/ctype_extra_sources.c strings/str_test strings/test_decimal +support-files/*.ini support-files/MacOSX/Description.plist support-files/MacOSX/Info.plist support-files/MacOSX/ReadMe.txt @@ -1294,5 +1311,8 @@ vio/test-sslserver vio/viotest-ssl vio/viotest-sslconnect.cpp vio/viotest.cpp +win/configure.data +win/vs71cache.txt +win/vs8cache.txt zlib/*.ds? zlib/*.vcproj diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 57061f3dbff..8055f337821 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -1,6 +1,6 @@ #!/bin/sh -if ! test -f sql/mysqld.cc +if test ! -f sql/mysqld.cc then echo "You must run this script from the MySQL top-level directory" exit 1 @@ -122,12 +122,6 @@ fi # (returns 0 if finds lines) if ccache -V > /dev/null 2>&1 then - if ! (echo "$CC" | grep "ccache" > /dev/null) - then - CC="ccache $CC" - fi - if ! (echo "$CXX" | grep "ccache" > /dev/null) - then - CXX="ccache $CXX" - fi + echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC" + echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX" fi diff --git a/BUILD/check-cpu b/BUILD/check-cpu index dc894c91cbd..fb69fd0acae 100755 --- a/BUILD/check-cpu +++ b/BUILD/check-cpu @@ -3,209 +3,216 @@ # Check cpu of current machine and find the # best compiler optimization flags for gcc # -# -if test -r /proc/cpuinfo ; then - # on Linux (and others?) we can get detailed CPU information out of /proc - cpuinfo="cat /proc/cpuinfo" +check_cpu () { + if test -r /proc/cpuinfo ; then + # on Linux (and others?) we can get detailed CPU information out of /proc + cpuinfo="cat /proc/cpuinfo" - # detect CPU family - cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` - if test -z "$cpu_family" ; then - cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` - fi + # detect CPU family + cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` + if test -z "$cpu_family" ; then + cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` + fi - # detect CPU vendor and model - cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` - model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1` - if test -z "$model_name" ; then - model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1` - fi + # detect CPU vendor and model + cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` + model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1` + if test -z "$model_name" ; then + model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1` + fi + + # fallback: get CPU model from uname output + if test -z "$model_name" ; then + model_name=`uname -m` + fi - # fallback: get CPU model from uname output - if test -z "$model_name" ; then - model_name=`uname -m` + # parse CPU flags + for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //'`; do + eval cpu_flag_$flag=yes + done + else + # Fallback when there is no /proc/cpuinfo + case "`uname -s`" in + FreeBSD|OpenBSD) + cpu_family=`uname -m`; + model_name=`sysctl -n hw.model` + ;; + Darwin) + cpu_family=`uname -p` + model_name=`machine` + ;; + *) + cpu_family=`uname -m`; + model_name=`uname -p`; + ;; + esac fi - # parse CPU flags - for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //'`; do - eval cpu_flag_$flag=yes - done -else - # Fallback when there is no /proc/cpuinfo - case "`uname -s`" in - FreeBSD|OpenBSD) - cpu_family=`uname -m`; - model_name=`sysctl -n hw.model` - ;; - Darwin) - cpu_family=`uname -p` - model_name=`machine` + # detect CPU shortname as used by gcc options + # this list is not complete, feel free to add further entries + cpu_arg="" + case "$cpu_family--$model_name" in + # DEC Alpha + Alpha*EV6*) + cpu_arg="ev6"; ;; - *) - cpu_family=`uname -m`; - model_name=`uname -p`; + + # Intel ia32 + *Xeon*) + # a Xeon is just another pentium4 ... + # ... unless it has the "lm" (long-mode) flag set, + # in that case it's a Xeon with EM64T support + if [ -z "$cpu_flag_lm" ]; then + cpu_arg="pentium4"; + else + cpu_arg="nocona"; + fi ;; - esac -fi - -# detect CPU shortname as used by gcc options -# this list is not complete, feel free to add further entries -cpu_arg="" -case "$cpu_family--$model_name" in - # DEC Alpha - Alpha*EV6*) - cpu_arg="ev6"; + *Pentium*4*Mobile*) + cpu_arg="pentium4m"; ;; - - # Intel ia32 - *Xeon*) - # a Xeon is just another pentium4 ... - # ... unless it has the "lm" (long-mode) flag set, - # in that case it's a Xeon with EM64T support - if [ -z "$cpu_flag_lm" ]; then + *Pentium*4*) cpu_arg="pentium4"; - else - cpu_arg="nocona"; - fi - ;; - *Pentium*4*Mobile*) - cpu_arg="pentium4m"; - ;; - *Pentium*4*) - cpu_arg="pentium4"; - ;; - *Pentium*III*Mobile*) - cpu_arg="pentium3m"; - ;; - *Pentium*III*) - cpu_arg="pentium3"; - ;; - *Pentium*M*pro*) - cpu_arg="pentium-m"; - ;; - *Athlon*64*) - cpu_arg="athlon64"; + ;; + *Pentium*III*Mobile*) + cpu_arg="pentium3m"; ;; - *Athlon*) - cpu_arg="athlon"; + *Pentium*III*) + cpu_arg="pentium3"; ;; - *Opteron*) - cpu_arg="opteron"; + *Pentium*M*pro*) + cpu_arg="pentium-m"; ;; + *Athlon*64*) + cpu_arg="athlon64"; + ;; + *Athlon*) + cpu_arg="athlon"; + ;; + *Opteron*) + cpu_arg="opteron"; + ;; + # MacOSX / Intel + *i386*i486*) + cpu_arg="pentium-m"; + ;; - # Intel ia64 - *Itanium*) - # Don't need to set any flags for itanium(at the moment) - cpu_arg=""; - ;; + # Intel ia64 + *Itanium*) + # Don't need to set any flags for itanium(at the moment) + cpu_arg=""; + ;; - # - *ppc*) - cpu_arg='powerpc' - ;; - - *powerpc*) - cpu_arg='powerpc' - ;; + # + *ppc*) + cpu_arg='powerpc' + ;; + + *powerpc*) + cpu_arg='powerpc' + ;; - # unknown - *) - cpu_arg=""; - ;; -esac - - -if test -z "$cpu_arg"; then - echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." - check_cpu_cflags="" - return -fi - -# different compiler versions have different option names -# for CPU specific command line options -if test -z "$CC" ; then - cc="gcc"; -else - cc=$CC -fi - -cc_ver=`$cc --version | sed 1q` -cc_verno=`echo $cc_ver | sed -e 's/[^0-9. ]//g; s/^ *//g; s/ .*//g'` - -case "$cc_ver--$cc_verno" in - *GCC*) - # different gcc backends (and versions) have different CPU flags - case `gcc -dumpmachine` in - i?86-*) - case "$cc_verno" in - 3.4*|3.5*|4.*) - check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg' - ;; - *) - check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg' - ;; - esac - ;; - ppc-*) - check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg' - ;; - x86_64-*) - check_cpu_args='-mtune=$cpu_arg' - ;; - *) - check_cpu_cflags="" - return - ;; - esac - ;; - 2.95.*) - # GCC 2.95 doesn't expose its name in --version output - check_cpu_args='-m$cpu_arg' - ;; - *) + # unknown + *) + cpu_arg=""; + ;; + esac + + + if test -z "$cpu_arg"; then + echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." >&2 check_cpu_cflags="" return - ;; -esac - -# now we check whether the compiler really understands the cpu type -touch __test.c - -while [ "$cpu_arg" ] ; do - echo -n testing $cpu_arg "... " - - # compile check - check_cpu_cflags=`eval echo $check_cpu_args` - if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then - echo ok - break; fi - echo failed - check_cpu_cflags="" + # different compiler versions have different option names + # for CPU specific command line options + if test -z "$CC" ; then + cc="gcc"; + else + cc=$CC + fi - # if compile failed: check whether it supports a predecessor of this CPU - # this list is not complete, feel free to add further entries - case "$cpu_arg" in - # Intel ia32 - nocona) cpu_arg=pentium4 ;; - prescott) cpu_arg=pentium4 ;; - pentium4m) cpu_arg=pentium4 ;; - pentium4) cpu_arg=pentium3 ;; - pentium3m) cpu_arg=pentium3 ;; - pentium3) cpu_arg=pentium2 ;; - pentium2) cpu_arg=pentiumpro ;; - pentiumpro) cpu_arg=pentium ;; - pentium) cpu_arg=i486 ;; - i486) cpu_arg=i386 ;; - - # power / powerPC - 7450) cpu_arg=7400 ;; - - *) cpu_arg="" ;; + cc_ver=`$cc --version | sed 1q` + cc_verno=`echo $cc_ver | sed -e 's/^.*gcc/gcc/g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'` + + case "$cc_ver--$cc_verno" in + *GCC*) + # different gcc backends (and versions) have different CPU flags + case `gcc -dumpmachine` in + i?86-*) + case "$cc_verno" in + 3.4*|3.5*|4.*) + check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg' + ;; + *) + check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg' + ;; + esac + ;; + ppc-*) + check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg' + ;; + x86_64-*) + check_cpu_args='-mtune=$cpu_arg' + ;; + *) + check_cpu_cflags="" + return + ;; + esac + ;; + 2.95.*) + # GCC 2.95 doesn't expose its name in --version output + check_cpu_args='-m$cpu_arg' + ;; + *) + check_cpu_cflags="" + return + ;; esac -done -rm __test.* + # now we check whether the compiler really understands the cpu type + touch __test.c + + while [ "$cpu_arg" ] ; do + # FIXME: echo -n isn't portable - see contortions autoconf goes through + echo -n testing $cpu_arg "... " >&2 + + # compile check + check_cpu_cflags=`eval echo $check_cpu_args` + if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then + echo ok >&2 + break; + fi + + echo failed >&2 + check_cpu_cflags="" + + # if compile failed: check whether it supports a predecessor of this CPU + # this list is not complete, feel free to add further entries + case "$cpu_arg" in + # Intel ia32 + nocona) cpu_arg=pentium4 ;; + prescott) cpu_arg=pentium4 ;; + pentium4m) cpu_arg=pentium4 ;; + pentium4) cpu_arg=pentium3 ;; + pentium3m) cpu_arg=pentium3 ;; + pentium3) cpu_arg=pentium2 ;; + pentium2) cpu_arg=pentiumpro ;; + pentiumpro) cpu_arg=pentium ;; + pentium) cpu_arg=i486 ;; + i486) cpu_arg=i386 ;; + + # power / powerPC + 7450) cpu_arg=7400 ;; + + *) cpu_arg="" ;; + esac + done + + rm __test.* +} +check_cpu diff --git a/BUILD/compile-ndb-autotest b/BUILD/compile-ndb-autotest new file mode 100755 index 00000000000..be28cc28346 --- /dev/null +++ b/BUILD/compile-ndb-autotest @@ -0,0 +1,19 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_configs="$max_configs --with-ndb-test --with-ndb-ccflags='-DERROR_INSERT'" +if [ "$full_debug" ] +then + extra_flags="$debug_cflags" + c_warnings="$c_warnings $debug_extra_warnings" + cxx_warnings="$cxx_warnings $debug_extra_warnings" + extra_configs="$debug_configs $extra_configs" +else + extra_flags="$fast_cflags" +fi + +extra_flags="$extra_flags $max_cflags -g" + +. "$path/FINISH.sh" diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed new file mode 100644 index 00000000000..d4d681937a2 --- /dev/null +++ b/BitKeeper/etc/collapsed @@ -0,0 +1,4 @@ +44d03f27qNdqJmARzBoP3Is_cN5e0w +44ec850ac2k4y2Omgr92GiWPBAVKGQ +44edb86b1iE5knJ97MbliK_3lCiAXA +44f33f3aj5KW5qweQeekY1LU0E9ZCg diff --git a/BitKeeper/etc/config b/BitKeeper/etc/config index 6d06edd193e..1a027813ff4 100644 --- a/BitKeeper/etc/config +++ b/BitKeeper/etc/config @@ -75,5 +75,6 @@ hours: [tomas:]checkout:get [guilhem:]checkout:get [pekka:]checkout:get +[msvensson:]checkout:get checkout:edit eoln:unix diff --git a/BitKeeper/triggers/post-commit b/BitKeeper/triggers/post-commit index 22d183eae3a..981b55c66ec 100755 --- a/BitKeeper/triggers/post-commit +++ b/BitKeeper/triggers/post-commit @@ -6,6 +6,13 @@ COMMITS=commits@lists.mysql.com DOCS=docs-commit@mysql.com LIMIT=10000 VERSION="5.0" +BKROOT=`bk root` + +if [ -x /usr/sbin/sendmail ]; then + SENDMAIL=/usr/sbin/sendmail +else + SENDMAIL=sendmail +fi if [ "$REAL_EMAIL" = "" ] then @@ -58,7 +65,9 @@ $BH EOF bk changes -v -r+ bk cset -r+ -d - ) | /usr/sbin/sendmail -t + ) > $BKROOT/BitKeeper/tmp/dev_public.txt + +$SENDMAIL -t < $BKROOT/BitKeeper/tmp/dev_public.txt #++ # commits@ mail @@ -82,7 +91,9 @@ see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html EOF bk changes -v -r+ bk cset -r+ -d - ) | head -n $LIMIT | /usr/sbin/sendmail -t + ) | bk sed -e ${LIMIT}q > $BKROOT/BitKeeper/tmp/commits.txt + +$SENDMAIL -t < $BKROOT/BitKeeper/tmp/commits.txt #++ # docs-commit@ mail @@ -102,7 +113,8 @@ Subject: bk commit - $VERSION tree (Manual) ($CHANGESET)$BS EOF bk changes -v -r+ bk cset -r+ -d - ) | /usr/sbin/sendmail -t + ) > $BKROOT/BitKeeper/tmp/docs.txt + $SENDMAIL -t < $BKROOT/BitKeeper/tmp/docs.txt fi else diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 00000000000..fd780ec6a13 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,132 @@ +PROJECT(MySql) + +# This reads user configuration, generated by configure.js. +INCLUDE(win/configure.data) + +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in + ${CMAKE_SOURCE_DIR}/include/mysql_version.h @ONLY) + +# Set standard options +ADD_DEFINITIONS(-D WITH_MYISAM_STORAGE_ENGINE) +ADD_DEFINITIONS(-D CMAKE_BUILD) +ADD_DEFINITIONS(-D HAVE_YASSL) + +SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisam_plugin") + + +IF(WITH_ARCHIVE_STORAGE_ENGINE) + ADD_DEFINITIONS(-D HAVE_ARCHIVE_DB) +ENDIF(WITH_ARCHIVE_STORAGE_ENGINE) + +IF (WITH_HEAP_STORAGE_ENGINE) + ADD_DEFINITIONS(-D WITH_HEAP_STORAGE_ENGINE) + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_heap_plugin") +ENDIF (WITH_HEAP_STORAGE_ENGINE) + +IF (WITH_MYISAMMRG_STORAGE_ENGINE) + ADD_DEFINITIONS(-D WITH_MYISAMMRG_STORAGE_ENGINE) + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisammrg_plugin") +ENDIF (WITH_MYISAMMRG_STORAGE_ENGINE) + +IF(WITH_INNOBASE_STORAGE_ENGINE) + CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/innobase/ib_config.h.in + ${CMAKE_SOURCE_DIR}/innobase/ib_config.h @ONLY) + ADD_DEFINITIONS(-D HAVE_INNOBASE_DB) + ADD_DEFINITIONS(-D WITH_INNOBASE_STORAGE_ENGINE) + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_innobase_plugin") +ENDIF(WITH_INNOBASE_STORAGE_ENGINE) + +IF(WITH_FEDERATED_STORAGE_ENGINE) + ADD_DEFINITIONS(-D HAVE_FEDERATED_DB) + ADD_DEFINITIONS(-D WITH_FEDERATED_STORAGE_ENGINE) + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_federated_plugin") +ENDIF(WITH_FEDERATED_STORAGE_ENGINE) + +IF(WITH_BERKELEY_STORAGE_ENGINE) + ADD_DEFINITIONS(-D HAVE_BERKELEY_DB) + ADD_DEFINITIONS(-D WITH_BERKELEY_STORAGE_ENGINE) + SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_berkeley_plugin") +ENDIF(WITH_BERKELEY_STORAGE_ENGINE) + +IF (WITH_BLACKHOLE_STORAGE_ENGINE) + ADD_DEFINITIONS(-D HAVE_BLACKHOLE_DB) +ENDIF (WITH_BLACKHOLE_STORAGE_ENGINE) + +SET(localstatedir "C:\\mysql\\data") +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-huge.cnf.sh + ${CMAKE_SOURCE_DIR}/support-files/my-huge.ini @ONLY) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-innodb-heavy-4G.cnf.sh + ${CMAKE_SOURCE_DIR}/support-files/my-innodb-heavy-4G.ini @ONLY) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-large.cnf.sh + ${CMAKE_SOURCE_DIR}/support-files/my-large.ini @ONLY) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-medium.cnf.sh + ${CMAKE_SOURCE_DIR}/support-files/my-medium.ini @ONLY) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-small.cnf.sh + ${CMAKE_SOURCE_DIR}/support-files/my-small.ini @ONLY) + +IF(__NT__) + ADD_DEFINITIONS(-D __NT__) +ENDIF(__NT__) +IF(CYBOZU) + ADD_DEFINITIONS(-D CYBOZU) +ENDIF(CYBOZU) + +# in some places we use DBUG_OFF +SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D DBUG_OFF") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D DBUG_OFF") + +IF(CMAKE_GENERATOR MATCHES "Visual Studio 8") + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /wd4996") + SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4996") + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /wd4996") + SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /wd4996") +ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8") + +IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR + CMAKE_GENERATOR MATCHES "Visual Studio 8") + # replace /MDd with /MTd + STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT + ${CMAKE_CXX_FLAGS_DEBUG_INIT}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT + ${CMAKE_C_FLAGS_DEBUG_INIT}) + STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE + ${CMAKE_C_FLAGS_RELEASE}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG + ${CMAKE_C_FLAGS_DEBUG}) + STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE + ${CMAKE_CXX_FLAGS_RELEASE}) + STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG + ${CMAKE_CXX_FLAGS_DEBUG}) + + # remove support for Exception handling + STRING(REPLACE "/GX" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_INIT + ${CMAKE_CXX_FLAGS_INIT}) + STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_DEBUG_INIT + ${CMAKE_CXX_FLAGS_DEBUG_INIT}) +ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR + CMAKE_GENERATOR MATCHES "Visual Studio 8") + +ADD_DEFINITIONS("-D_WINDOWS -D__WIN__ -D _CRT_SECURE_NO_DEPRECATE") + +ADD_SUBDIRECTORY(vio) +ADD_SUBDIRECTORY(dbug) +ADD_SUBDIRECTORY(strings) +ADD_SUBDIRECTORY(regex) +ADD_SUBDIRECTORY(mysys) +ADD_SUBDIRECTORY(extra/yassl) +ADD_SUBDIRECTORY(extra/yassl/taocrypt) +ADD_SUBDIRECTORY(extra) +ADD_SUBDIRECTORY(zlib) +ADD_SUBDIRECTORY(heap) +ADD_SUBDIRECTORY(myisam) +ADD_SUBDIRECTORY(myisammrg) +ADD_SUBDIRECTORY(client) +ADD_SUBDIRECTORY(bdb) +ADD_SUBDIRECTORY(innobase) +ADD_SUBDIRECTORY(sql) +ADD_SUBDIRECTORY(sql/examples) +ADD_SUBDIRECTORY(server-tools/instance-manager) +ADD_SUBDIRECTORY(libmysql) +ADD_SUBDIRECTORY(tests) diff --git a/Makefile.am b/Makefile.am index f0784a9baed..d48f0e24966 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = foreign # These are built from source in the Docs directory EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ - README COPYING EXCEPTIONS-CLIENT + README COPYING EXCEPTIONS-CLIENT CMakeLists.txt SUBDIRS = . include @docs_dirs@ @zlib_dir@ @yassl_dir@ \ @readline_topdir@ sql-common \ @thread_dirs@ pstack \ @@ -33,7 +33,7 @@ DIST_SUBDIRS = . include @docs_dirs@ zlib \ @thread_dirs@ pstack \ @sql_union_dirs@ scripts @man_dirs@ tests SSL\ BUILD netware os2 @libmysqld_dirs@ \ - @bench_dirs@ support-files @tools_dirs@ + @bench_dirs@ support-files @tools_dirs@ win # Run these targets before any others, also make part of clean target, # to make sure we create new links after a clean. diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln index bd0cae1d5d8..1e3a33b8eb4 100644 --- a/VC++Files/mysql.sln +++ b/VC++Files/mysql.sln @@ -174,7 +174,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlimport", "client\mysql {44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_upgrade", "client\mysql_upgrade.vcproj", "{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_upgrade", "client\mysql_upgrade.vcproj", "{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}" ProjectSection(ProjectDependencies) = postProject {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} = {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} {26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB} @@ -990,6 +990,33 @@ Global {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.Build.0 = Release|Win32 {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.ActiveCfg = Release|Win32 {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic.ActiveCfg = classic|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic.Build.0 = classic|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic nt.ActiveCfg = classic|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic nt.Build.0 = classic|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Debug.ActiveCfg = Debug|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Debug.Build.0 = Debug|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Classic.ActiveCfg = classic|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Debug.ActiveCfg = Debug|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Pro.ActiveCfg = classic|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_ProGPL.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Release.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max nt.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max nt.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.nt.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.nt.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl nt.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl nt.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro nt.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro nt.Build.0 = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Release.ActiveCfg = Release|Win32 + {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Release.Build.0 = Release|Win32 {94B86159-C581-42CD-825D-C69CBC237E5C}.classic.ActiveCfg = Release|Win32 {94B86159-C581-42CD-825D-C69CBC237E5C}.classic.Build.0 = Release|Win32 {94B86159-C581-42CD-825D-C69CBC237E5C}.classic nt.ActiveCfg = Release|Win32 diff --git a/VC++Files/mysys/mysys.dsp b/VC++Files/mysys/mysys.dsp index 935f1411530..0f1b4bd5d54 100644 --- a/VC++Files/mysys/mysys.dsp +++ b/VC++Files/mysys/mysys.dsp @@ -457,6 +457,10 @@ SOURCE=.\my_malloc.c # End Source File # Begin Source File +SOURCE=.\my_memmem.c +# End Source File +# Begin Source File + SOURCE=.\my_messnc.c # End Source File # Begin Source File diff --git a/VC++Files/sql/mysqld.dsp b/VC++Files/sql/mysqld.dsp index 259c044e390..45c5e75beb5 100644 --- a/VC++Files/sql/mysqld.dsp +++ b/VC++Files/sql/mysqld.dsp @@ -1639,7 +1639,7 @@ SOURCE=.\sql_load.cpp # End Source File # Begin Source File -SOURCE=.\sql\sql_locale.cpp +SOURCE=.\sql_locale.cpp # End Source File # Begin Source File diff --git a/bdb/CMakeLists.txt b/bdb/CMakeLists.txt new file mode 100755 index 00000000000..c5dd60852d4 --- /dev/null +++ b/bdb/CMakeLists.txt @@ -0,0 +1,44 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/bdb/build_win32 + ${CMAKE_SOURCE_DIR}/bdb/dbinc + ${CMAKE_SOURCE_DIR}/bdb) + +# BDB needs a number of source files that are auto-generated by the unix +# configure. So to build BDB, it is necessary to copy these over to the Windows +# bitkeeper tree, or to use a source .tar.gz package which already has these +# files. +ADD_LIBRARY(bdb btree/bt_compare.c btree/bt_conv.c btree/bt_curadj.c btree/bt_cursor.c + btree/bt_delete.c btree/bt_method.c btree/bt_open.c btree/bt_put.c btree/bt_rec.c + btree/bt_reclaim.c btree/bt_recno.c btree/bt_rsearch.c btree/bt_search.c + btree/bt_split.c btree/bt_stat.c btree/bt_upgrade.c btree/bt_verify.c btree/btree_auto.c + db/crdel_auto.c db/crdel_rec.c db/db.c db/db_am.c db/db_auto.c common/db_byteorder.c + db/db_cam.c db/db_conv.c db/db_dispatch.c db/db_dup.c common/db_err.c common/db_getlong.c + common/db_idspace.c db/db_iface.c db/db_join.c common/db_log2.c db/db_meta.c + db/db_method.c db/db_open.c db/db_overflow.c db/db_pr.c db/db_rec.c db/db_reclaim.c + db/db_remove.c db/db_rename.c db/db_ret.c env/db_salloc.c env/db_shash.c db/db_truncate.c + db/db_upg.c db/db_upg_opd.c db/db_vrfy.c db/db_vrfyutil.c dbm/dbm.c dbreg/dbreg.c + dbreg/dbreg_auto.c dbreg/dbreg_rec.c dbreg/dbreg_util.c env/env_file.c env/env_method.c + env/env_open.c env/env_recover.c env/env_region.c fileops/fileops_auto.c fileops/fop_basic.c + fileops/fop_rec.c fileops/fop_util.c hash/hash.c hash/hash_auto.c hash/hash_conv.c + hash/hash_dup.c hash/hash_func.c hash/hash_meta.c hash/hash_method.c hash/hash_open.c + hash/hash_page.c hash/hash_rec.c hash/hash_reclaim.c hash/hash_stat.c hash/hash_upgrade.c + hash/hash_verify.c hmac/hmac.c hsearch/hsearch.c lock/lock.c lock/lock_deadlock.c + lock/lock_method.c lock/lock_region.c lock/lock_stat.c lock/lock_util.c log/log.c + log/log_archive.c log/log_compare.c log/log_get.c log/log_method.c log/log_put.c + mp/mp_alloc.c mp/mp_bh.c mp/mp_fget.c mp/mp_fopen.c mp/mp_fput.c + mp/mp_fset.c mp/mp_method.c mp/mp_region.c mp/mp_register.c mp/mp_stat.c mp/mp_sync.c + mp/mp_trickle.c mutex/mut_tas.c mutex/mut_win32.c mutex/mutex.c os_win32/os_abs.c + os/os_alloc.c os_win32/os_clock.c os_win32/os_config.c os_win32/os_dir.c os_win32/os_errno.c + os_win32/os_fid.c os_win32/os_fsync.c os_win32/os_handle.c os/os_id.c os_win32/os_map.c + os/os_method.c os/os_oflags.c os_win32/os_open.c os/os_region.c os_win32/os_rename.c + os/os_root.c os/os_rpath.c os_win32/os_rw.c os_win32/os_seek.c os_win32/os_sleep.c + os_win32/os_spin.c os_win32/os_stat.c os/os_tmpdir.c os_win32/os_type.c os/os_unlink.c + qam/qam.c qam/qam_auto.c qam/qam_conv.c qam/qam_files.c qam/qam_method.c qam/qam_open.c + qam/qam_rec.c qam/qam_stat.c qam/qam_upgrade.c qam/qam_verify.c rep/rep_method.c + rep/rep_record.c rep/rep_region.c rep/rep_util.c hmac/sha1.c + clib/strcasecmp.c txn/txn.c txn/txn_auto.c txn/txn_method.c txn/txn_rec.c + txn/txn_recover.c txn/txn_region.c txn/txn_stat.c txn/txn_util.c common/util_log.c + common/util_sig.c xa/xa.c xa/xa_db.c xa/xa_map.c) + diff --git a/bdb/Makefile.in b/bdb/Makefile.in index c83d40ac8b2..d40fffed769 100644 --- a/bdb/Makefile.in +++ b/bdb/Makefile.in @@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@ # distdir and top_distdir are set by the calling Makefile bdb_build = build_unix -files = LICENSE Makefile Makefile.in README +files = LICENSE Makefile Makefile.in README CMakeLists.txt subdirs = btree build_vxworks build_win32 clib common cxx db dbinc \ dbinc_auto db185 db_archive db_checkpoint db_deadlock db_dump \ db_dump185 db_load db_printlog db_recover db_stat db_upgrade \ diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100755 index 00000000000..3e7f1a48c70 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,79 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +# The old Windows build method used renamed (.cc -> .cpp) source files, fails +# in #include in mysqlbinlog.cc. So disable that using the USING_CMAKE define. +ADD_DEFINITIONS(-DUSING_CMAKE) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/libmysql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/mysys + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/strings) + +ADD_LIBRARY(mysqlclient ../mysys/array.c ../strings/bchange.c ../strings/bmove.c + ../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c + ../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c + ../strings/ctype-cp932.c ../strings/ctype-czech.c ../strings/ctype-euc_kr.c + ../strings/ctype-eucjpms.c ../strings/ctype-extra.c ../strings/ctype-gb2312.c + ../strings/ctype-gbk.c ../strings/ctype-latin1.c ../strings/ctype-mb.c + ../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c + ../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c + ../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c + ../mysys/default.c ../libmysql/errmsg.c ../mysys/errors.c + ../libmysql/get_password.c ../strings/int2str.c ../strings/is_prefix.c + ../libmysql/libmysql.c ../mysys/list.c ../strings/llstr.c + ../strings/longlong2str.c ../libmysql/manager.c ../mysys/mf_cache.c + ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c + ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c + ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c + ../mysys/mf_wcomp.c ../mysys/mulalloc.c ../mysys/my_access.c ../mysys/my_alloc.c + ../mysys/my_chsize.c ../mysys/my_compress.c ../mysys/my_create.c + ../mysys/my_delete.c ../mysys/my_div.c ../mysys/my_error.c ../mysys/my_file.c + ../mysys/my_fopen.c ../mysys/my_fstream.c ../mysys/my_gethostbyname.c + ../mysys/my_getopt.c ../mysys/my_getwd.c ../mysys/my_init.c ../mysys/my_lib.c + ../mysys/my_malloc.c ../mysys/my_messnc.c ../mysys/my_net.c ../mysys/my_once.c + ../mysys/my_open.c ../mysys/my_pread.c ../mysys/my_pthread.c ../mysys/my_read.c + ../mysys/my_realloc.c ../mysys/my_rename.c ../mysys/my_seek.c + ../mysys/my_static.c ../strings/my_strtoll10.c ../mysys/my_symlink.c + ../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c + ../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c + ../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c + ../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c + ../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c + ../strings/strfill.c ../mysys/string.c ../strings/strinstr.c ../strings/strmake.c + ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c + ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c + ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c + ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c) + +ADD_DEPENDENCIES(mysqlclient GenError) +ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc) +LINK_DIRECTORIES(${MYSQL_BINARY_DIR}/mysys ${MYSQL_BINARY_DIR}/zlib) +TARGET_LINK_LIBRARIES(mysql mysqlclient mysys yassl taocrypt zlib dbug wsock32) + +ADD_EXECUTABLE(mysqltest mysqltest.c) +TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys yassl taocrypt zlib dbug regex wsock32) + +ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) +TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient dbug yassl taocrypt zlib wsock32) + +ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c) +TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug yassl taocrypt zlib wsock32) + +ADD_EXECUTABLE(mysqlimport mysqlimport.c) +TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wsock32) + +ADD_EXECUTABLE(mysqlshow mysqlshow.c) +TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32) + +ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc + ../mysys/my_bit.c ../mysys/my_bitmap.c + ../mysys/base64.c) +TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient dbug yassl taocrypt zlib wsock32) + +ADD_EXECUTABLE(mysqladmin mysqladmin.cc) +TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug yassl taocrypt zlib wsock32) + diff --git a/client/Makefile.am b/client/Makefile.am index 5787905fd35..d3c320db56c 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -47,7 +47,9 @@ mysqltestmanager_pwgen_SOURCES = mysqlmanager-pwgen.c mysqltestmanagerc_SOURCES= mysqlmanagerc.c $(yassl_dummy_link_fix) mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix) mysqlshow_SOURCES= mysqlshow.c $(yassl_dummy_link_fix) -mysqldump_SOURCES= mysqldump.c my_user.c $(yassl_dummy_link_fix) +mysqldump_SOURCES= mysqldump.c my_user.c \ + $(top_srcdir)/mysys/mf_getdate.c \ + $(yassl_dummy_link_fix) mysqlimport_SOURCES= mysqlimport.c $(yassl_dummy_link_fix) mysql_upgrade_SOURCES= mysql_upgrade.c $(yassl_dummy_link_fix) sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc @@ -58,6 +60,8 @@ DEFS = -DUNDEF_THREADS_HACK \ -DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \ -DDATADIR="\"$(localstatedir)\"" +EXTRA_DIST = get_password.c CMakeLists.txt + link_sources: for f in $(sql_src) ; do \ rm -f $$f; \ diff --git a/client/mysql.cc b/client/mysql.cc index 94b43d030e8..5e09c309917 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -136,7 +136,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, tty_password= 0, opt_nobeep=0, opt_reconnect=1, default_charset_used= 0, opt_secure_auth= 0, default_pager_set= 0, opt_sigint_ignore= 0, - show_warnings = 0; + show_warnings= 0; +static volatile int executing_query= 0, interrupted_query= 0; static ulong opt_max_allowed_packet, opt_net_buffer_length; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static my_string opt_mysql_unix_port=0; @@ -338,6 +339,7 @@ static void end_timer(ulong start_time,char *buff); static void mysql_end_timer(ulong start_time,char *buff); static void nice_time(double sec,char *buff,bool part_second); static sig_handler mysql_end(int sig); +static sig_handler mysql_sigint(int sig); int main(int argc,char *argv[]) @@ -420,7 +422,7 @@ int main(int argc,char *argv[]) if (opt_sigint_ignore) signal(SIGINT, SIG_IGN); else - signal(SIGINT, mysql_end); // Catch SIGINT to clean up + signal(SIGINT, mysql_sigint); // Catch SIGINT to clean up signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up /* @@ -488,6 +490,28 @@ int main(int argc,char *argv[]) #endif } +sig_handler mysql_sigint(int sig) +{ + char kill_buffer[40]; + MYSQL *kill_mysql= NULL; + + signal(SIGINT, mysql_sigint); + + /* terminate if no query being executed, or we already tried interrupting */ + if (!executing_query || interrupted_query++) + mysql_end(sig); + + kill_mysql= mysql_init(kill_mysql); + if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password, + "", opt_mysql_port, opt_mysql_unix_port,0)) + mysql_end(sig); + /* kill_buffer is always big enough because max length of %lu is 15 */ + sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql)); + mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer)); + mysql_close(kill_mysql); + tee_fprintf(stdout, "Query aborted by Ctrl+C\n"); +} + sig_handler mysql_end(int sig) { mysql_close(&mysql); @@ -577,13 +601,13 @@ static struct my_option my_long_options[] = {"force", 'f', "Continue even if we get an sql error.", (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-named-commands", 'g', - "Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"named-commands", 'G', "Enable named commands. Named commands mean this program's internal commands; see mysql> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.", (gptr*) &named_cmds, (gptr*) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"no-named-commands", 'g', + "Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.", @@ -602,13 +626,6 @@ static struct my_option my_long_options[] = NO_ARG, 1, 0, 0, 0, 0, 0}, {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef USE_POPEN - {"no-pager", OPT_NOPAGER, - "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, {"unbuffered", 'n', "Flush buffer after each query.", (gptr*) &unbuffered, (gptr*) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"column-names", OPT_COLUMN_NAMES, "Write column names in results.", @@ -628,8 +645,11 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef USE_POPEN {"pager", OPT_PAGER, - "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode.", + "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"no-pager", OPT_NOPAGER, + "Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"password", 'p', "Password to use when connecting to server. If password is not given it's asked from the tty.", @@ -670,8 +690,10 @@ static struct my_option my_long_options[] = {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag, (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"tee", OPT_TEE, - "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode.", + "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DONT_ALLOW_USER_CHANGE {"user", 'u', "User for login if not current user.", (gptr*) ¤t_user, (gptr*) ¤t_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -1008,6 +1030,8 @@ static int read_and_execute(bool interactive) if (opt_outfile && glob_buffer.is_empty()) fflush(OUTFILE); + interrupted_query= 0; + #if defined( __WIN__) || defined(OS2) || defined(__NETWARE__) tee_fputs(prompt, stdout); #if defined(__NETWARE__) @@ -1221,7 +1245,8 @@ static bool add_line(String &buffer,char *line,char *in_string, continue; } #endif - if (!*ml_comment && inchar == '\\') + if (!*ml_comment && inchar == '\\' && + !(mysql.server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)) { // Found possbile one character command like \c @@ -1794,7 +1819,14 @@ static int com_server_help(String *buffer __attribute__((unused)), if (help_arg[0] != '\'') { - (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS); + char *end_arg= strend(help_arg); + if(--end_arg) + { + while (my_isspace(charset_info,*end_arg)) + end_arg--; + *++end_arg= '\0'; + } + (void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS); server_cmd= cmd_buf; } @@ -1880,9 +1912,13 @@ com_help(String *buffer __attribute__((unused)), { reg1 int i, j; char * help_arg= strchr(line,' '), buff[32], *end; - if (help_arg) - return com_server_help(buffer,line,help_arg+1); + { + while (my_isspace(charset_info,*help_arg)) + help_arg++; + if (*help_arg) + return com_server_help(buffer,line,help_arg); + } put_info("\nFor information about MySQL products and services, visit:\n" " http://www.mysql.com/\n" @@ -1938,6 +1974,9 @@ com_charset(String *buffer __attribute__((unused)), char *line) if (new_cs) { charset_info= new_cs; + mysql_set_character_set(&mysql, charset_info->csname); + default_charset= (char *)charset_info->csname; + default_charset_used= 1; put_info("Charset changed", INFO_INFO); } else put_info("Charset is not found", INFO_INFO); @@ -1997,6 +2036,8 @@ com_go(String *buffer,char *line __attribute__((unused))) timer=start_timer(); + executing_query= 1; + error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length()); #ifdef HAVE_READLINE @@ -2011,6 +2052,7 @@ com_go(String *buffer,char *line __attribute__((unused))) if (error) { buffer->length(0); // Remove query on error + executing_query= 0; return error; } error=0; @@ -2021,13 +2063,19 @@ com_go(String *buffer,char *line __attribute__((unused))) if (quick) { if (!(result=mysql_use_result(&mysql)) && mysql_field_count(&mysql)) + { + executing_query= 0; return put_error(&mysql); + } } else { error= mysql_store_result_for_lazy(&result); if (error) + { + executing_query= 0; return error; + } } if (verbose >= 3 || !opt_silent) @@ -2088,6 +2136,9 @@ com_go(String *buffer,char *line __attribute__((unused))) fflush(stdout); mysql_free_result(result); } while (!(err= mysql_next_result(&mysql))); + + executing_query= 0; + if (err >= 1) error= put_error(&mysql); @@ -2270,10 +2321,8 @@ print_table_data(MYSQL_RES *result) MYSQL_ROW cur; MYSQL_FIELD *field; bool *num_flag; - bool *not_null_flag; num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result)); - not_null_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result)); if (info_flag) { print_field_types(result); @@ -2303,11 +2352,15 @@ print_table_data(MYSQL_RES *result) (void) tee_fputs("|", PAGER); for (uint off=0; (field = mysql_fetch_field(result)) ; off++) { - tee_fprintf(PAGER, " %-*s |",(int) min(field->max_length, + uint name_length= (uint) strlen(field->name); + uint numcells= charset_info->cset->numcells(charset_info, + field->name, + field->name + name_length); + uint display_length= field->max_length + name_length - numcells; + tee_fprintf(PAGER, " %-*s |",(int) min(display_length, MAX_COLUMN_LENGTH), - field->name); + field->name); num_flag[off]= IS_NUM(field->type); - not_null_flag[off]= IS_NOT_NULL(field->flags); } (void) tee_fputs("\n", PAGER); tee_puts((char*) separator.ptr(), PAGER); @@ -2328,7 +2381,7 @@ print_table_data(MYSQL_RES *result) uint extra_padding; /* If this column may have a null value, use "NULL" for empty. */ - if (! not_null_flag[off] && (cur[off] == NULL)) + if (cur[off] == NULL) { buffer= "NULL"; data_length= 4; @@ -2368,7 +2421,6 @@ print_table_data(MYSQL_RES *result) } tee_puts((char*) separator.ptr(), PAGER); my_afree((gptr) num_flag); - my_afree((gptr) not_null_flag); } @@ -2858,7 +2910,7 @@ com_connect(String *buffer, char *line) bzero(buff, sizeof(buff)); if (buffer) { - strmov(buff, line); + strmake(buff, line, sizeof(buff)); tmp= get_arg(buff, 0); if (tmp && *tmp) { @@ -3642,12 +3694,14 @@ static const char* construct_prompt() case 'U': if (!full_username) init_username(); - processed_prompt.append(full_username); + processed_prompt.append(full_username ? full_username : + (current_user ? current_user : "(unknown)")); break; case 'u': if (!full_username) init_username(); - processed_prompt.append(part_username); + processed_prompt.append(part_username ? part_username : + (current_user ? current_user : "(unknown)")); break; case PROMPT_CHAR: processed_prompt.append(PROMPT_CHAR); @@ -3724,6 +3778,9 @@ static const char* construct_prompt() case 't': processed_prompt.append('\t'); break; + case 'l': + processed_prompt.append(delimiter_str); + break; default: processed_prompt.append(c); } diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 3288b627554..6ec361392c8 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -17,6 +17,14 @@ #include "client_priv.h" #include <my_dir.h> +#ifdef __WIN__ +const char *mysqlcheck_name= "mysqlcheck.exe"; +const char *mysql_name= "mysql.exe"; +#else +const char *mysqlcheck_name= "mysqlcheck"; +const char *mysql_name= "mysql"; +#endif /*__WIN__*/ + static my_bool opt_force= 0, opt_verbose= 0, tty_password= 0; static char *user= (char*) "root", *basedir= 0, *datadir= 0, *opt_password= 0; static my_bool upgrade_defaults_created= 0; @@ -65,7 +73,7 @@ static struct my_option my_long_options[]= }; static const char *load_default_groups[]= { - "mysql_upgrade", "client", 0 + "mysql_upgrade", 0 }; #include <help_end.h> @@ -149,17 +157,29 @@ static int create_defaults_file(const char *path, const char *our_defaults_path) File our_defaults_file, defaults_file; char buffer[512]; char *buffer_end; + int failed_to_open_count= 0; int error; /* check if the defaults file is needed at all */ if (!opt_password) return 0; - defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY, +retry_open: + defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY | O_EXCL, MYF(MY_FAE | MY_WME)); if (defaults_file < 0) - return 1; + { + if (failed_to_open_count == 0) + { + remove(path); + failed_to_open_count+= 1; + goto retry_open; + } + else + return 1; + } + upgrade_defaults_created= 1; if (our_defaults_path) { @@ -180,7 +200,7 @@ static int create_defaults_file(const char *path, const char *our_defaults_path) } buffer_end= strnmov(buffer, "\n[client]", sizeof(buffer)); if (opt_password) - buffer_end= strxnmov(buffer, sizeof(buffer), + buffer_end= strxnmov(buffer_end, sizeof(buffer), "\npassword=", opt_password, NullS); error= my_write(defaults_file, buffer, (int) (buffer_end - buffer), MYF(MY_WME | MY_FNABP)); @@ -272,7 +292,7 @@ int main(int argc, char **argv) strmake(bindir_end, "/bin", sizeof(bindir) - (int) (bindir_end - bindir)-1); if (!test_file_exists_res - (bindir, "mysqlcheck", mysqlcheck_line, &mysqlcheck_end)) + (bindir, mysqlcheck_name, mysqlcheck_line, &mysqlcheck_end)) { printf("Can't find program '%s'\n", mysqlcheck_line); puts("Please restart with --basedir=mysql-install-directory"); @@ -342,7 +362,8 @@ int main(int argc, char **argv) goto err_exit; fix_priv_tables: - if (!test_file_exists_res(bindir, "mysql", fix_priv_tables_cmd, &fix_cmd_end)) + if (!test_file_exists_res(bindir, mysql_name, + fix_priv_tables_cmd, &fix_cmd_end)) { puts("Could not find MySQL command-line client (mysql)."); puts diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 518ab7cf832..c04c2ecabd6 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -36,6 +36,7 @@ /* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */ #include "mysql_priv.h" #include "log_event.h" +#include "sql_common.h" #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -1077,7 +1078,7 @@ could be out of memory"); const char *error_msg; Log_event *ev; - len = net_safe_read(mysql); + len= cli_safe_read(mysql); if (len == packet_error) { fprintf(stderr, "Got error reading packet from server: %s\n", @@ -1489,14 +1490,13 @@ int main(int argc, char** argv) the server */ -#ifdef __WIN__ #include "my_decimal.h" #include "decimal.c" + +#if defined(__WIN__) && !defined(CMAKE_BUILD) #include "my_decimal.cpp" #include "log_event.cpp" #else -#include "my_decimal.h" -#include "decimal.c" #include "my_decimal.cc" #include "log_event.cc" #endif diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 804fa14956f..5d87a4fd23c 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -458,7 +458,7 @@ static int process_all_tables_in_db(char *database) LINT_INIT(res); if (use_db(database)) return 1; - if (mysql_query(sock, "SHOW TABLES") || + if (mysql_query(sock, "SHOW TABLE STATUS") || !((res= mysql_store_result(sock)))) return 1; @@ -484,8 +484,12 @@ static int process_all_tables_in_db(char *database) } for (end = tables + 1; (row = mysql_fetch_row(res)) ;) { - end= fix_table_name(end, row[0]); - *end++= ','; + /* Skip tables with an engine of NULL (probably a view). */ + if (row[1]) + { + end= fix_table_name(end, row[0]); + *end++= ','; + } } *--end = 0; if (tot_length) @@ -495,7 +499,11 @@ static int process_all_tables_in_db(char *database) else { while ((row = mysql_fetch_row(res))) - handle_request_for_tables(row[0], strlen(row[0])); + /* Skip tables with an engine of NULL (probably a view). */ + if (row[1]) + { + handle_request_for_tables(row[0], strlen(row[0])); + } } mysql_free_result(res); return 0; diff --git a/client/mysqldump.c b/client/mysqldump.c index e3c13bb0451..116bbed6ec2 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -83,8 +83,9 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length, static char *alloc_query_str(ulong size); static char *field_escape(char *to,const char *from,uint length); -static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1, - lock_tables=1,ignore_errors=0,flush_logs=0, +static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, + quick= 1, extended_insert= 1, + lock_tables=1,ignore_errors=0,flush_logs=0,flush_privileges=0, opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0, opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0, opt_alldbs=0,opt_create_db=0,opt_lock_all_tables=0, @@ -96,7 +97,7 @@ static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1, opt_complete_insert= 0, opt_drop_database= 0, opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1; static ulong opt_max_allowed_packet, opt_net_buffer_length; -static MYSQL mysql_connection,*sock=0; +static MYSQL mysql_connection,*mysql=0; static my_bool insert_pat_inited=0; static DYNAMIC_STRING insert_pat; static char *opt_password=0,*current_user=0, @@ -255,6 +256,12 @@ static struct my_option my_long_options[] = "--lock-all-tables or --master-data with --flush-logs", (gptr*) &flush_logs, (gptr*) &flush_logs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"flush-privileges", OPT_ESC, "Emit a FLUSH PRIVILEGES statement " + "after dumping the mysql database. This option should be used any " + "time the dump contains the mysql database and any other database " + "that depends on the data in the mysql database for proper restore. ", + (gptr*) &flush_privileges, (gptr*) &flush_privileges, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, {"force", 'f', "Continue even if we get an sql-error.", (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -312,9 +319,10 @@ static struct my_option my_long_options[] = (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-info", 't', "Don't write table creation info.", - (gptr*) &tFlag, (gptr*) &tFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-data", 'd', "No row information.", (gptr*) &dFlag, (gptr*) &dFlag, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_no_create_info, (gptr*) &opt_no_create_info, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"no-data", 'd', "No row information.", (gptr*) &opt_no_data, + (gptr*) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-set-names", 'N', "Deprecated. Use --skip-set-charset instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -415,7 +423,9 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, int string_value); static int dump_selected_tables(char *db, char **table_names, int tables); static int dump_all_tables_in_db(char *db); -static int init_dumping(char *); +static int init_dumping_views(char *); +static int init_dumping_tables(char *); +static int init_dumping(char *, int init_func(char*)); static int dump_databases(char **); static int dump_all_databases(); static char *quote_name(const char *name, char *buff, my_bool force); @@ -427,6 +437,30 @@ static my_bool dump_all_views_in_db(char *database); #include <help_start.h> /* + Print the supplied message if in verbose mode + + SYNOPSIS + verbose_msg() + fmt format specifier + ... variable number of parameters +*/ + +static void verbose_msg(const char *fmt, ...) +{ + va_list args; + DBUG_ENTER("verbose_msg"); + + if (!verbose) + DBUG_VOID_RETURN; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + DBUG_VOID_RETURN; +} + +/* exit with message if ferror(file) SYNOPSIS @@ -565,6 +599,13 @@ static void write_footer(FILE *sql_file) fprintf(sql_file, "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n"); fputs("\n", sql_file); + if (opt_comments) + { + char time_str[20]; + get_date(time_str, GETDATE_DATE_TIME, 0); + fprintf(sql_file, "-- Dump completed on %s\n", + time_str); + } check_io(sql_file); } } /* write_footer */ @@ -815,8 +856,9 @@ static int get_options(int *argc, char ***argv) static void DB_error(MYSQL *mysql, const char *when) { DBUG_ENTER("DB_error"); - my_printf_error(0,"Got error: %d: %s %s", MYF(0), - mysql_errno(mysql), mysql_error(mysql), when); + fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname, + mysql_errno(mysql), mysql_error(mysql), when); + fflush(stderr); safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; } /* DB_error */ @@ -844,9 +886,10 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, if (mysql_query(mysql_con, query) || (res && !((*res)= mysql_store_result(mysql_con)))) { - my_printf_error(0, "%s: Couldn't execute '%s': %s (%d)", - MYF(0), my_progname, query, - mysql_error(mysql_con), mysql_errno(mysql_con)); + fprintf(stderr, "%s: Couldn't execute '%s': %s (%d)\n", + my_progname, query, + mysql_error(mysql_con), mysql_errno(mysql_con)); + safe_exit(EX_MYSQLERR); return 1; } return 0; @@ -880,8 +923,8 @@ static void safe_exit(int error) first_error= error; if (ignore_errors) return; - if (sock) - mysql_close(sock); + if (mysql) + mysql_close(mysql); exit(error); } /* safe_exit */ @@ -894,10 +937,8 @@ static int dbConnect(char *host, char *user,char *passwd) { char buff[20+FN_REFLEN]; DBUG_ENTER("dbConnect"); - if (verbose) - { - fprintf(stderr, "-- Connecting to %s...\n", host ? host : "localhost"); - } + + verbose_msg("-- Connecting to %s...\n", host ? host : "localhost"); mysql_init(&mysql_connection); if (opt_compress) mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS); @@ -915,7 +956,7 @@ static int dbConnect(char *host, char *user,char *passwd) mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); - if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, + if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, 0))) { @@ -931,12 +972,11 @@ static int dbConnect(char *host, char *user,char *passwd) As we're going to set SQL_MODE, it would be lost on reconnect, so we cannot reconnect. */ - sock->reconnect= 0; + mysql->reconnect= 0; my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); - if (mysql_query_with_error_report(sock, 0, buff)) + if (mysql_query_with_error_report(mysql, 0, buff)) { - mysql_close(sock); safe_exit(EX_MYSQLERR); return 1; } @@ -947,9 +987,8 @@ static int dbConnect(char *host, char *user,char *passwd) if (opt_tz_utc) { my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */"); - if (mysql_query_with_error_report(sock, 0, buff)) + if (mysql_query_with_error_report(mysql, 0, buff)) { - mysql_close(sock); safe_exit(EX_MYSQLERR); return 1; } @@ -963,9 +1002,8 @@ static int dbConnect(char *host, char *user,char *passwd) */ static void dbDisconnect(char *host) { - if (verbose) - fprintf(stderr, "-- Disconnecting from %s...\n", host ? host : "localhost"); - mysql_close(sock); + verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost"); + mysql_close(mysql); } /* dbDisconnect */ @@ -1258,7 +1296,7 @@ static uint dump_routines_for_db(char *db) DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); - mysql_real_escape_string(sock, db_name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); /* nice comments */ if (opt_comments) @@ -1269,7 +1307,7 @@ static uint dump_routines_for_db(char *db) enough privileges to lock mysql.proc. */ if (lock_tables) - mysql_query(sock, "LOCK TABLES mysql.proc READ"); + mysql_query(mysql, "LOCK TABLES mysql.proc READ"); fprintf(sql_file, "DELIMITER ;;\n"); @@ -1280,7 +1318,7 @@ static uint dump_routines_for_db(char *db) "SHOW %s STATUS WHERE Db = '%s'", routine_type[i], db_name_buff); - if (mysql_query_with_error_report(sock, &routine_list_res, query_buff)) + if (mysql_query_with_error_report(mysql, &routine_list_res, query_buff)) DBUG_RETURN(1); if (mysql_num_rows(routine_list_res)) @@ -1294,7 +1332,7 @@ static uint dump_routines_for_db(char *db) my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s", routine_type[i], routine_name); - if (mysql_query_with_error_report(sock, &routine_res, query_buff)) + if (mysql_query_with_error_report(mysql, &routine_res, query_buff)) DBUG_RETURN(1); while ((row= mysql_fetch_row(routine_res))) @@ -1376,7 +1414,7 @@ static uint dump_routines_for_db(char *db) fprintf(sql_file, "DELIMITER ;\n"); if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); DBUG_RETURN(0); } @@ -1418,10 +1456,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED)) { delayed= 0; - if (verbose) - fprintf(stderr, - "-- Warning: Unable to use delayed inserts for table '%s' " - "because it's of type %s\n", table, table_type); + verbose_msg("-- Warning: Unable to use delayed inserts for table '%s' " + "because it's of type %s\n", table, table_type); } complete_insert= 0; @@ -1437,8 +1473,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : delayed ? " DELAYED " : opt_ignore ? " IGNORE " : ""); - if (verbose) - fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); + verbose_msg("-- Retrieving table structure for table %s...\n", table); len= my_snprintf(query_buff, sizeof(query_buff), "SET OPTION SQL_QUOTE_SHOW_CREATE=%d", @@ -1453,17 +1488,17 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (opt_order_by_primary) order_by = primary_key_fields(result_table); - if (!opt_xml && !mysql_query_with_error_report(sock, 0, query_buff)) + if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff)) { /* using SHOW CREATE statement */ - if (!tFlag) + if (!opt_no_create_info) { /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; MYSQL_FIELD *field; my_snprintf(buff, sizeof(buff), "show create table %s", result_table); - if (mysql_query_with_error_report(sock, 0, buff)) + if (mysql_query_with_error_report(mysql, 0, buff)) { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); @@ -1499,14 +1534,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, check_io(sql_file); } - result= mysql_store_result(sock); + result= mysql_store_result(mysql); field= mysql_fetch_field_direct(result, 0); if (strcmp(field->name, "View") == 0) { char *scv_buff = NULL; - if (verbose) - fprintf(stderr, "-- It's a view, create dummy table for view\n"); + verbose_msg("-- It's a view, create dummy table for view\n"); /* save "show create" statement for later */ if ((row= mysql_fetch_row(result)) && (scv_buff=row[1])) @@ -1527,7 +1561,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, */ my_snprintf(query_buff, sizeof(query_buff), "SHOW FIELDS FROM %s", result_table); - if (mysql_query_with_error_report(sock, 0, query_buff)) + if (mysql_query_with_error_report(mysql, 0, query_buff)) { /* View references invalid or privileged table/col/fun (err 1356), @@ -1535,7 +1569,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, a comment with the view's 'show create' statement. (Bug #17371) */ - if (mysql_errno(sock) == ER_VIEW_INVALID) + if (mysql_errno(mysql) == ER_VIEW_INVALID) fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : ""); my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); @@ -1546,7 +1580,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, else my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); - if ((result= mysql_store_result(sock))) + if ((result= mysql_store_result(mysql))) { if (mysql_num_rows(result)) { @@ -1599,7 +1633,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, } my_snprintf(query_buff, sizeof(query_buff), "show fields from %s", result_table); - if (mysql_query_with_error_report(sock, &result, query_buff)) + if (mysql_query_with_error_report(mysql, &result, query_buff)) { if (path) my_fclose(sql_file, MYF(MY_WME)); @@ -1649,21 +1683,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, } else { - if (verbose) - fprintf(stderr, - "%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n", - my_progname, mysql_error(sock)); + verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n", + my_progname, mysql_error(mysql)); my_snprintf(query_buff, sizeof(query_buff), "show fields from %s", result_table); - if (mysql_query_with_error_report(sock, &result, query_buff)) + if (mysql_query_with_error_report(mysql, &result, query_buff)) { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } /* Make an sql-file, if path was given iow. option -T was given */ - if (!tFlag) + if (!opt_no_create_info) { if (path) { @@ -1707,7 +1739,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, ulong *lengths= mysql_fetch_lengths(result); if (init) { - if (!opt_xml && !tFlag) + if (!opt_xml && !opt_no_create_info) { fputs(",\n",sql_file); check_io(sql_file); @@ -1719,7 +1751,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (opt_complete_insert) dynstr_append(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); - if (!tFlag) + if (!opt_no_create_info) { if (opt_xml) { @@ -1749,22 +1781,22 @@ static uint get_table_structure(char *table, char *db, char *table_type, } num_fields= mysql_num_rows(result); mysql_free_result(result); - if (!tFlag) + if (!opt_no_create_info) { /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; uint keynr,primary_key; my_snprintf(buff, sizeof(buff), "show keys from %s", result_table); - if (mysql_query_with_error_report(sock, &result, buff)) + if (mysql_query_with_error_report(mysql, &result, buff)) { - if (mysql_errno(sock) == ER_WRONG_OBJECT) + if (mysql_errno(mysql) == ER_WRONG_OBJECT) { /* it is VIEW */ fputs("\t\t<options Comment=\"view\" />\n", sql_file); goto continue_xml; } fprintf(stderr, "%s: Can't get keys for table %s (%s)\n", - my_progname, result_table, mysql_error(sock)); + my_progname, result_table, mysql_error(mysql)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); @@ -1837,21 +1869,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(buff, sizeof(buff), "show table status like %s", quote_for_like(table, show_name_buff)); - if (mysql_query_with_error_report(sock, &result, buff)) + if (mysql_query_with_error_report(mysql, &result, buff)) { - if (mysql_errno(sock) != ER_PARSE_ERROR) + if (mysql_errno(mysql) != ER_PARSE_ERROR) { /* If old MySQL version */ - if (verbose) - fprintf(stderr, - "-- Warning: Couldn't get status information for table %s (%s)\n", - result_table,mysql_error(sock)); + verbose_msg("-- Warning: Couldn't get status information for " \ + "table %s (%s)\n", result_table,mysql_error(mysql)); } } else if (!(row= mysql_fetch_row(result))) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", - result_table,mysql_error(sock)); + result_table,mysql_error(mysql)); } else { @@ -1924,7 +1954,7 @@ static void dump_triggers_for_table (char *table, char *db) "SHOW TRIGGERS LIKE %s", quote_for_like(table, name_buff)); - if (mysql_query_with_error_report(sock, &result, query_buff)) + if (mysql_query_with_error_report(mysql, &result, query_buff)) { if (path) my_fclose(sql_file, MYF(MY_WME)); @@ -2094,12 +2124,10 @@ static void dump_table(char *table, char *db) return; /* Check --no-data flag */ - if (dFlag) + if (opt_no_data) { - if (verbose) - fprintf(stderr, - "-- Skipping dump data for table '%s', --no-data was used\n", - table); + verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n", + table); DBUG_VOID_RETURN; } @@ -2112,27 +2140,22 @@ static void dump_table(char *table, char *db) */ if (ignore_flag & IGNORE_DATA) { - if (verbose) - fprintf(stderr, - "-- Warning: Skipping data for table '%s' because it's of type %s\n", - table, table_type); + verbose_msg("-- Warning: Skipping data for table '%s' because " \ + "it's of type %s\n", table, table_type); DBUG_VOID_RETURN; } /* Check that there are any fields in the table */ if (num_fields == 0) { - if (verbose) - fprintf(stderr, - "-- Skipping dump data for table '%s', it has no fields\n", - table); + verbose_msg("-- Skipping dump data for table '%s', it has no fields\n", + table); DBUG_VOID_RETURN; } result_table= quote_name(table,table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); - if (verbose) - fprintf(stderr, "-- Sending SELECT query...\n"); + verbose_msg("-- Sending SELECT query...\n"); if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; @@ -2170,9 +2193,9 @@ static void dump_table(char *table, char *db) if (order_by) end = strxmov(end, " ORDER BY ", order_by, NullS); } - if (mysql_real_query(sock, query, (uint) (end - query))) + if (mysql_real_query(mysql, query, (uint) (end - query))) { - DB_error(sock, "when executing 'SELECT INTO OUTFILE'"); + DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); DBUG_VOID_RETURN; } } @@ -2218,19 +2241,22 @@ static void dump_table(char *table, char *db) fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query_with_error_report(sock, 0, query)) - DB_error(sock, "when retrieving data from server"); + if (mysql_query_with_error_report(mysql, 0, query)) + { + DB_error(mysql, "when retrieving data from server"); + goto err; + } if (quick) - res=mysql_use_result(sock); + res=mysql_use_result(mysql); else - res=mysql_store_result(sock); + res=mysql_store_result(mysql); if (!res) { - DB_error(sock, "when retrieving data from server"); + DB_error(mysql, "when retrieving data from server"); goto err; } - if (verbose) - fprintf(stderr, "-- Retrieving rows...\n"); + + verbose_msg("-- Retrieving rows...\n"); if (mysql_num_fields(res) != num_fields) { fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n", @@ -2499,13 +2525,13 @@ static void dump_table(char *table, char *db) fputs(";\n", md_result_file); /* If not empty table */ fflush(md_result_file); check_io(md_result_file); - if (mysql_errno(sock)) + if (mysql_errno(mysql)) { my_snprintf(query, QUERY_LENGTH, "%s: Error %d: %s when dumping table %s at row: %ld\n", my_progname, - mysql_errno(sock), - mysql_error(sock), + mysql_errno(mysql), + mysql_error(mysql), result_table, rownr); fputs(query,stderr); @@ -2551,7 +2577,7 @@ static char *getTableName(int reset) if (!res) { - if (!(res = mysql_list_tables(sock,NullS))) + if (!(res = mysql_list_tables(mysql,NullS))) return(NULL); } if ((row = mysql_fetch_row(res))) @@ -2574,7 +2600,7 @@ static int dump_all_databases() MYSQL_RES *tableres; int result=0; - if (mysql_query_with_error_report(sock, &tableres, "SHOW DATABASES")) + if (mysql_query_with_error_report(mysql, &tableres, "SHOW DATABASES")) return 1; while ((row = mysql_fetch_row(tableres))) { @@ -2583,11 +2609,11 @@ static int dump_all_databases() } if (seen_views) { - if (mysql_query(sock, "SHOW DATABASES") || - !(tableres = mysql_store_result(sock))) + if (mysql_query(mysql, "SHOW DATABASES") || + !(tableres = mysql_store_result(mysql))) { my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s", - MYF(0), mysql_error(sock)); + MYF(0), mysql_error(mysql)); return 1; } while ((row = mysql_fetch_row(tableres))) @@ -2622,15 +2648,84 @@ static int dump_databases(char **db_names) } /* dump_databases */ -static int init_dumping(char *database) +/* +View Specific database initalization. + +SYNOPSIS + init_dumping_views + qdatabase quoted name of the database + +RETURN VALUES + 0 Success. + 1 Failure. +*/ +int init_dumping_views(char *qdatabase) +{ + return 0; +} /* init_dumping_views */ + + +/* +Table Specific database initalization. + +SYNOPSIS + init_dumping_tables + qdatabase quoted name of the database + +RETURN VALUES + 0 Success. + 1 Failure. +*/ +int init_dumping_tables(char *qdatabase) +{ + if (!opt_create_db) + { + char qbuf[256]; + MYSQL_ROW row; + MYSQL_RES *dbinfo; + + my_snprintf(qbuf, sizeof(qbuf), + "SHOW CREATE DATABASE IF NOT EXISTS %s", + qdatabase); + + if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql))) + { + /* Old server version, dump generic CREATE DATABASE */ + if (opt_drop_database) + fprintf(md_result_file, + "\n/*!40000 DROP DATABASE IF EXISTS %s;*/\n", + qdatabase); + fprintf(md_result_file, + "\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n", + qdatabase); + } + else + { + if (opt_drop_database) + fprintf(md_result_file, + "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n", + qdatabase); + row = mysql_fetch_row(dbinfo); + if (row[1]) + { + fprintf(md_result_file,"\n%s;\n",row[1]); + } + } + } + + return 0; +} /* init_dumping_tables */ + + +static int init_dumping(char *database, int init_func(char*)) { - if (mysql_get_server_version(sock) >= 50003 && + if (mysql_get_server_version(mysql) >= 50003 && !my_strcasecmp(&my_charset_latin1, database, "information_schema")) return 1; - if (mysql_select_db(sock, database)) + if (mysql_select_db(mysql, database)) { - DB_error(sock, "when selecting the database"); + DB_error(mysql, "when selecting the database"); return 1; /* If --force */ } if (!path && !opt_xml) @@ -2647,40 +2742,10 @@ static int init_dumping(char *database) fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase); check_io(md_result_file); } - if (!opt_create_db) - { - char qbuf[256]; - MYSQL_ROW row; - MYSQL_RES *dbinfo; - my_snprintf(qbuf, sizeof(qbuf), - "SHOW CREATE DATABASE IF NOT EXISTS %s", - qdatabase); + /* Call the view or table specific function */ + init_func(qdatabase); - if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) - { - /* Old server version, dump generic CREATE DATABASE */ - if (opt_drop_database) - fprintf(md_result_file, - "\n/*!40000 DROP DATABASE IF EXISTS %s;*/\n", - qdatabase); - fprintf(md_result_file, - "\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n", - qdatabase); - } - else - { - if (opt_drop_database) - fprintf(md_result_file, - "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n", - qdatabase); - row = mysql_fetch_row(dbinfo); - if (row[1]) - { - fprintf(md_result_file,"\n%s;\n",row[1]); - } - } - } fprintf(md_result_file,"\nUSE %s;\n", qdatabase); check_io(md_result_file); } @@ -2708,11 +2773,12 @@ static int dump_all_tables_in_db(char *database) char hash_key[2*NAME_LEN+2]; /* "db.tablename" */ char *afterdot; + int using_mysql_db= my_strcasecmp(&my_charset_latin1, database, "mysql"); afterdot= strmov(hash_key, database); *afterdot++= '.'; - if (init_dumping(database)) + if (init_dumping(database, init_dumping_tables)) return 1; if (opt_xml) print_xml_tag1(md_result_file, "", "database name=", database, "\n"); @@ -2725,15 +2791,15 @@ static int dump_all_tables_in_db(char *database) dynstr_append(&query, quote_name(table, table_buff, 1)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } - if (numrows && mysql_real_query(sock, query.str, query.length-1)) - DB_error(sock, "when using LOCK TABLES"); + if (numrows && mysql_real_query(mysql, query.str, query.length-1)) + DB_error(mysql, "when using LOCK TABLES"); /* We shall continue here, if --force was given */ dynstr_free(&query); } if (flush_logs) { - if (mysql_refresh(sock, REFRESH_LOG)) - DB_error(sock, "when doing refresh"); + if (mysql_refresh(mysql, REFRESH_LOG)) + DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ } while ((table= getTableName(0))) @@ -2745,12 +2811,12 @@ static int dump_all_tables_in_db(char *database) my_free(order_by, MYF(MY_ALLOW_ZERO_PTR)); order_by= 0; if (opt_dump_triggers && ! opt_xml && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) dump_triggers_for_table(table, database); } } if (opt_routines && !opt_xml && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", database)); dump_routines_for_db(database); @@ -2761,7 +2827,12 @@ static int dump_all_tables_in_db(char *database) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); + if (flush_privileges && using_mysql_db == 0) + { + fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n"); + fprintf(md_result_file,"\n/*! FLUSH PRIVILEGES */;\n"); + } return 0; } /* dump_all_tables_in_db */ @@ -2784,23 +2855,8 @@ static my_bool dump_all_views_in_db(char *database) uint numrows; char table_buff[NAME_LEN*2+3]; - if (mysql_select_db(sock, database)) - { - DB_error(sock, "when selecting the database"); + if (init_dumping(database, init_dumping_views)) return 1; - } - if (opt_databases || opt_alldbs) - { - char quoted_database_buf[NAME_LEN*2+3]; - char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted); - if (opt_comments) - { - fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase); - check_io(md_result_file); - } - fprintf(md_result_file,"\nUSE %s;\n", qdatabase); - check_io(md_result_file); - } if (opt_xml) print_xml_tag1(md_result_file, "", "database name=", database, "\n"); if (lock_tables) @@ -2812,15 +2868,15 @@ static my_bool dump_all_views_in_db(char *database) dynstr_append(&query, quote_name(table, table_buff, 1)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } - if (numrows && mysql_real_query(sock, query.str, query.length-1)) - DB_error(sock, "when using LOCK TABLES"); + if (numrows && mysql_real_query(mysql, query.str, query.length-1)) + DB_error(mysql, "when using LOCK TABLES"); /* We shall continue here, if --force was given */ dynstr_free(&query); } if (flush_logs) { - if (mysql_refresh(sock, REFRESH_LOG)) - DB_error(sock, "when doing refresh"); + if (mysql_refresh(mysql, REFRESH_LOG)) + DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ } while ((table= getTableName(0))) @@ -2831,7 +2887,7 @@ static my_bool dump_all_views_in_db(char *database) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); return 0; } /* dump_all_tables_in_db */ @@ -2861,12 +2917,12 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root) my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s", quote_for_like(old_table_name, show_name_buff)); - if (mysql_query_with_error_report(sock, 0, query)) + if (mysql_query_with_error_report(mysql, 0, query)) { safe_exit(EX_MYSQLERR); } - if ((table_res= mysql_store_result(sock))) + if ((table_res= mysql_store_result(mysql))) { my_ulonglong num_rows= mysql_num_rows(table_res); if (num_rows > 0) @@ -2895,7 +2951,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) char **dump_tables, **pos, **end; DBUG_ENTER("dump_selected_tables"); - if (init_dumping(db)) + if (init_dumping(db, init_dumping_tables)) return 1; init_alloc_root(&root, 8192, 0); @@ -2928,16 +2984,16 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (lock_tables) { - if (mysql_real_query(sock, lock_tables_query.str, + if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) - DB_error(sock, "when doing LOCK TABLES"); + DB_error(mysql, "when doing LOCK TABLES"); /* We shall countinue here, if --force was given */ } dynstr_free(&lock_tables_query); if (flush_logs) { - if (mysql_refresh(sock, REFRESH_LOG)) - DB_error(sock, "when doing refresh"); + if (mysql_refresh(mysql, REFRESH_LOG)) + DB_error(mysql, "when doing refresh"); /* We shall countinue here, if --force was given */ } if (opt_xml) @@ -2949,7 +3005,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DBUG_PRINT("info",("Dumping table %s", *pos)); dump_table(*pos, db); if (opt_dump_triggers && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) dump_triggers_for_table(*pos, db); } @@ -2961,7 +3017,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } /* obtain dump of routines (procs/functions) */ if (opt_routines && !opt_xml && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", db)); dump_routines_for_db(db); @@ -2975,7 +3031,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); DBUG_RETURN(0); } /* dump_selected_tables */ @@ -2988,8 +3044,6 @@ static int do_show_master_status(MYSQL *mysql_con) (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : ""; if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS")) { - my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", - MYF(0), mysql_error(mysql_con)); return 1; } else @@ -3160,7 +3214,7 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, table_type Type of table GLOBAL VARIABLES - sock MySQL socket + mysql MySQL connection verbose Write warning messages RETURN @@ -3179,14 +3233,12 @@ char check_if_ignore_table(const char *table_name, char *table_type) DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff)); my_snprintf(buff, sizeof(buff), "show table status like %s", quote_for_like(table_name, show_name_buff)); - if (mysql_query_with_error_report(sock, &res, buff)) + if (mysql_query_with_error_report(mysql, &res, buff)) { - if (mysql_errno(sock) != ER_PARSE_ERROR) + if (mysql_errno(mysql) != ER_PARSE_ERROR) { /* If old MySQL version */ - if (verbose) - fprintf(stderr, - "-- Warning: Couldn't get status information for table %s (%s)\n", - table_name,mysql_error(sock)); + verbose_msg("-- Warning: Couldn't get status information for " \ + "table %s (%s)\n", table_name,mysql_error(mysql)); DBUG_RETURN(result); /* assume table is ok */ } } @@ -3194,7 +3246,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", - table_name, mysql_error(sock)); + table_name, mysql_error(mysql)); mysql_free_result(res); DBUG_RETURN(result); /* assume table is ok */ } @@ -3222,7 +3274,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) /* If these two types, we do want to skip dumping the table */ - if (!dFlag && + if (!opt_no_data && (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM"))) result= IGNORE_DATA; } @@ -3230,6 +3282,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) DBUG_RETURN(result); } + /* Get string of comma-separated primary key field names @@ -3259,12 +3312,12 @@ static char *primary_key_fields(const char *table_name) my_snprintf(show_keys_buff, sizeof(show_keys_buff), "SHOW KEYS FROM %s", table_name); - if (mysql_query(sock, show_keys_buff) || - !(res = mysql_store_result(sock))) + if (mysql_query(mysql, show_keys_buff) || + !(res = mysql_store_result(mysql))) { fprintf(stderr, "Warning: Couldn't read keys from table %s;" " records are NOT sorted (%s)\n", - table_name, mysql_error(sock)); + table_name, mysql_error(mysql)); /* Don't exit, because it's better to print out unsorted records */ goto cleanup; } @@ -3369,11 +3422,10 @@ static my_bool get_view_structure(char *table, char* db) FILE *sql_file = md_result_file; DBUG_ENTER("get_view_structure"); - if (tFlag) /* Don't write table creation info */ + if (opt_no_create_info) /* Don't write table creation info */ DBUG_RETURN(0); - if (verbose) - fprintf(stderr, "-- Retrieving view structure for table %s...\n", table); + verbose_msg("-- Retrieving view structure for table %s...\n", table); #ifdef NOT_REALLY_USED_YET sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", @@ -3384,7 +3436,7 @@ static my_bool get_view_structure(char *table, char* db) opt_quoted_table= quote_name(table, table_buff2, 0); my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table); - if (mysql_query_with_error_report(sock, &table_res, query)) + if (mysql_query_with_error_report(mysql, &table_res, query)) { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); @@ -3394,8 +3446,7 @@ static my_bool get_view_structure(char *table, char* db) field= mysql_fetch_field_direct(table_res, 0); if (strcmp(field->name, "View") != 0) { - if (verbose) - fprintf(stderr, "-- It's base table, skipped\n"); + verbose_msg("-- It's base table, skipped\n"); DBUG_RETURN(0); } @@ -3430,7 +3481,7 @@ static my_bool get_view_structure(char *table, char* db) "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE " \ "FROM information_schema.views " \ "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db); - if (mysql_query(sock, query)) + if (mysql_query(mysql, query)) { /* Use the raw output from SHOW CREATE TABLE if @@ -3456,7 +3507,7 @@ static my_bool get_view_structure(char *table, char* db) mysql_free_result(table_res); /* Get the result from "select ... information_schema" */ - if (!(table_res= mysql_store_result(sock)) || + if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { safe_exit(EX_MYSQLERR); @@ -3551,21 +3602,21 @@ int main(int argc, char **argv) write_header(md_result_file, *argv); if ((opt_lock_all_tables || opt_master_data) && - do_flush_tables_read_lock(sock)) + do_flush_tables_read_lock(mysql)) goto err; - if (opt_single_transaction && start_transaction(sock, test(opt_master_data))) + if (opt_single_transaction && start_transaction(mysql, test(opt_master_data))) goto err; - if (opt_delete_master_logs && do_reset_master(sock)) + if (opt_delete_master_logs && do_reset_master(mysql)) goto err; if (opt_lock_all_tables || opt_master_data) { - if (flush_logs && mysql_refresh(sock, REFRESH_LOG)) + if (flush_logs && mysql_refresh(mysql, REFRESH_LOG)) goto err; flush_logs= 0; /* not anymore; that would not be sensible */ } - if (opt_master_data && do_show_master_status(sock)) + if (opt_master_data && do_show_master_status(mysql)) goto err; - if (opt_single_transaction && do_unlock_tables(sock)) /* unlock but no commit! */ + if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */ goto err; if (opt_alldbs) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 1f9b96f91be..67659684c9c 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -521,7 +521,7 @@ int main(int argc, char **argv) return(1); /* purecov: deadcode */ } - if (mysql_query(sock, "set @@character_set_database=binary;")) + if (mysql_query(sock, "/*!40101 set @@character_set_database=binary */;")) { db_error(sock); /* We shall countinue here, if --force was given */ return(1); diff --git a/client/mysqlshow.c b/client/mysqlshow.c index d090495ff81..40405c53565 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -344,7 +344,7 @@ list_dbs(MYSQL *mysql,const char *wild) char query[255]; MYSQL_FIELD *field; MYSQL_RES *result; - MYSQL_ROW row, rrow; + MYSQL_ROW row= NULL, rrow; if (!(result=mysql_list_dbs(mysql,wild))) { @@ -352,6 +352,26 @@ list_dbs(MYSQL *mysql,const char *wild) mysql_error(mysql)); return 1; } + + /* + If a wildcard was used, but there was only one row and it's name is an + exact match, we'll assume they really wanted to see the contents of that + database. This is because it is fairly common for database names to + contain the underscore (_), like INFORMATION_SCHEMA. + */ + if (wild && mysql_num_rows(result) == 1) + { + row= mysql_fetch_row(result); + if (!my_strcasecmp(&my_charset_latin1, row[0], wild)) + { + mysql_free_result(result); + if (opt_status) + return list_table_status(mysql, wild, NULL); + else + return list_tables(mysql, wild, NULL); + } + } + if (wild) printf("Wildcard: %s\n",wild); @@ -368,7 +388,8 @@ list_dbs(MYSQL *mysql,const char *wild) else print_header(header,length,"Tables",6,"Total Rows",12,NullS); - while ((row = mysql_fetch_row(result))) + /* The first row may have already been read up above. */ + while (row || (row= mysql_fetch_row(result))) { counter++; @@ -422,6 +443,8 @@ list_dbs(MYSQL *mysql,const char *wild) print_row(row[0],length,tables,6,NullS); else print_row(row[0],length,tables,6,rows,12,NullS); + + row= NULL; } print_trailer(length, diff --git a/client/mysqltest.c b/client/mysqltest.c index 2fc09fbc3d2..0f0abe682b5 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -177,7 +177,7 @@ typedef struct static test_file file_stack[MAX_INCLUDE_DEPTH]; static test_file* cur_file; static test_file* file_stack_end; -uint start_lineno; /* Start line of query */ +uint start_lineno= 0; /* Start line of query */ static char TMPDIR[FN_REFLEN]; static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER; @@ -620,7 +620,7 @@ static void die(const char *fmt, ...) if (cur_file && cur_file != file_stack) fprintf(stderr, "In included file \"%s\": ", cur_file->file_name); - if (start_lineno != 0) + if (start_lineno > 0) fprintf(stderr, "At line %u: ", start_lineno); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); @@ -4757,6 +4757,14 @@ int main(int argc, char **argv) q->require_file=require_file; save_file[0]=0; } + /* + To force something being sent as a query to the mysqld one can + use the prefix "query". Remove "query" from string before executing + */ + if (strncmp(q->query, "query ", 6) == 0) + { + q->query= q->first_argument; + } run_query(&cur_con->mysql, q, flags); query_executed= 1; q->last_argument= q->end; @@ -4949,9 +4957,6 @@ int main(int argc, char **argv) die("No queries executed but result file found!"); } - - dynstr_free(&ds_res); - if (!got_end_timer) timer_output(); /* No end_timer cmd, end it */ free_used_memory(); diff --git a/config/ac-macros/openssl.m4 b/config/ac-macros/openssl.m4 index af4305486a3..3130cdc3437 100644 --- a/config/ac-macros/openssl.m4 +++ b/config/ac-macros/openssl.m4 @@ -30,8 +30,8 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [ OPENSSL_INCLUDE=-I$incs fi # Test for libssl using all known library file endings - if test -f $d/libssl.a || test -f $d/libssl.so || \ - test -f $d/libssl.sl || test -f $d/libssl.dylib ; then + if test -f $libs/libssl.a || test -f $libs/libssl.so || \ + test -f $libs/libssl.sl || test -f $libs/libssl.dylib ; then OPENSSL_LIB=$libs fi ;; diff --git a/configure.in b/configure.in index b49dffcb59f..34d94b4f7da 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.25) +AM_INIT_AUTOMAKE(mysql, 5.0.26) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 @@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=25 +NDB_VERSION_BUILD=26 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? @@ -2826,6 +2826,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl include/mysql_version.h dnl cmd-line-utils/Makefile dnl cmd-line-utils/libedit/Makefile dnl + win/Makefile dnl zlib/Makefile dnl cmd-line-utils/readline/Makefile) AC_CONFIG_COMMANDS([default], , test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h) diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt new file mode 100755 index 00000000000..fe20fdd3db6 --- /dev/null +++ b/dbug/CMakeLists.txt @@ -0,0 +1,5 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -D__WIN32__") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +ADD_LIBRARY(dbug dbug.c factorial.c sanity.c) diff --git a/dbug/Makefile.am b/dbug/Makefile.am index 38705e63847..57288d32431 100644 --- a/dbug/Makefile.am +++ b/dbug/Makefile.am @@ -22,7 +22,8 @@ noinst_HEADERS = dbug_long.h libdbug_a_SOURCES = dbug.c sanity.c EXTRA_DIST = example1.c example2.c example3.c \ user.r monty.doc readme.prof dbug_add_tags.pl \ - my_main.c main.c factorial.c dbug_analyze.c + my_main.c main.c factorial.c dbug_analyze.c \ + CMakeLists.txt NROFF_INC = example1.r example2.r example3.r main.r \ factorial.r output1.r output2.r output3.r \ output4.r output5.r diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt new file mode 100755 index 00000000000..50e0f04eb14 --- /dev/null +++ b/extra/CMakeLists.txt @@ -0,0 +1,32 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +ADD_EXECUTABLE(comp_err comp_err.c) +TARGET_LINK_LIBRARIES(comp_err dbug mysys strings wsock32) + +GET_TARGET_PROPERTY(COMP_ERR_EXE comp_err LOCATION) + +ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/include/mysqld_error.h + COMMAND ${COMP_ERR_EXE} + --charset=${PROJECT_SOURCE_DIR}/sql/share/charsets + --out-dir=${PROJECT_SOURCE_DIR}/sql/share/ + --header_file=${PROJECT_SOURCE_DIR}/include/mysqld_error.h + --name_file=${PROJECT_SOURCE_DIR}/include/mysqld_ername.h + --state_file=${PROJECT_SOURCE_DIR}/include/sql_state.h + --in_file=${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt + DEPENDS comp_err ${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt) + +ADD_CUSTOM_TARGET(GenError + ALL + DEPENDS ${PROJECT_SOURCE_DIR}/include/mysqld_error.h) + +ADD_EXECUTABLE(my_print_defaults my_print_defaults.c) +TARGET_LINK_LIBRARIES(my_print_defaults strings mysys dbug taocrypt odbc32 odbccp32 wsock32) + +ADD_EXECUTABLE(perror perror.c) +TARGET_LINK_LIBRARIES(perror strings mysys dbug wsock32) + +ADD_EXECUTABLE(replace replace.c) +TARGET_LINK_LIBRARIES(replace strings mysys dbug wsock32) diff --git a/extra/Makefile.am b/extra/Makefile.am index c0ad75059df..0de513ba15a 100644 --- a/extra/Makefile.am +++ b/extra/Makefile.am @@ -43,6 +43,7 @@ $(top_builddir)/include/sql_state.h: $(top_builddir)/include/mysqld_error.h bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \ resolve_stack_dump mysql_waitpid innochecksum noinst_PROGRAMS = charset2html +EXTRA_DIST = CMakeLists.txt # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/extra/comp_err.c b/extra/comp_err.c index 65fc131a5fc..14774c87a28 100644 --- a/extra/comp_err.c +++ b/extra/comp_err.c @@ -188,8 +188,9 @@ int main(int argc, char *argv[]) DBUG_RETURN(1); } clean_up(lang_head, error_head); + DBUG_LEAVE; /* we can't call my_end after DBUG_RETURN */ my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); - DBUG_RETURN(0); + return(0); } } diff --git a/extra/perror.c b/extra/perror.c index 82311c1b2c9..b26e516a101 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -218,8 +218,11 @@ int main(int argc,char *argv[]) On some system, like NETWARE, strerror(unknown_error) returns a string 'Unknown Error'. To avoid printing it we try to find the error string by asking for an impossible big error message. + + On Solaris 2.8 it might return NULL */ - msg= strerror(10000); + if ((msg= strerror(10000)) == NULL) + msg= "Unknown Error"; /* Allocate a buffer for unknown_error since strerror always returns @@ -258,7 +261,7 @@ int main(int argc,char *argv[]) found= 1; msg= 0; } - else + else #endif msg = strerror(code); @@ -278,20 +281,23 @@ int main(int argc,char *argv[]) else puts(msg); } - if (!(msg=get_ha_error_msg(code))) + + if (!found) { - if (!found) - { + /* Error message still not found, look in handler error codes */ + if (!(msg=get_ha_error_msg(code))) + { fprintf(stderr,"Illegal error code: %d\n",code); error=1; - } - } - else - { - if (verbose) - printf("MySQL error code %3d: %s\n",code,msg); - else - puts(msg); + } + else + { + found= 1; + if (verbose) + printf("MySQL error code %3d: %s\n",code,msg); + else + puts(msg); + } } } } diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt new file mode 100755 index 00000000000..e5429876072 --- /dev/null +++ b/extra/yassl/CMakeLists.txt @@ -0,0 +1,6 @@ +ADD_DEFINITIONS("-DWIN32 -D_LIB -DYASSL_PREFIX") + +INCLUDE_DIRECTORIES(include taocrypt/include mySTL) +ADD_LIBRARY(yassl src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp src/handshake.cpp src/lock.cpp + src/log.cpp src/socket_wrapper.cpp src/ssl.cpp src/timer.cpp src/yassl_error.cpp + src/yassl_imp.cpp src/yassl_int.cpp) diff --git a/extra/yassl/COPYING b/extra/yassl/COPYING new file mode 100644 index 00000000000..d60c31a97a5 --- /dev/null +++ b/extra/yassl/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/extra/yassl/Makefile.am b/extra/yassl/Makefile.am index d0415012767..12a7da1085b 100644 --- a/extra/yassl/Makefile.am +++ b/extra/yassl/Makefile.am @@ -1,2 +1,2 @@ SUBDIRS = taocrypt src testsuite -EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp) +EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp) CMakeLists.txt diff --git a/extra/yassl/include/openssl/generate_prefix_files.pl b/extra/yassl/include/openssl/generate_prefix_files.pl index b921ee11e9a..da591b31332 100755 --- a/extra/yassl/include/openssl/generate_prefix_files.pl +++ b/extra/yassl/include/openssl/generate_prefix_files.pl @@ -30,7 +30,7 @@ sub generate_prefix($$) next; } - if ( /^\s*[a-zA-Z0-9*_ ]+\s+([_a-zA-Z0-9]+)\s*\(/ ) + if ( /^\s*[a-zA-Z0-9*_ ]+\s+\*?([_a-zA-Z0-9]+)\s*\(/ ) { print OUT "#define $1 ya$1\n"; } diff --git a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h index 7f815156f47..aa3f799cf80 100644 --- a/extra/yassl/include/openssl/prefix_ssl.h +++ b/extra/yassl/include/openssl/prefix_ssl.h @@ -1,5 +1,6 @@ #define Copyright yaCopyright #define yaSSL_CleanUp yayaSSL_CleanUp +#define BN_bin2bn yaBN_bin2bn #define DH_new yaDH_new #define DH_free yaDH_free #define RSA_free yaRSA_free @@ -92,6 +93,12 @@ #define SSL_want_read yaSSL_want_read #define SSL_want_write yaSSL_want_write #define SSL_pending yaSSL_pending +#define SSLv3_method yaSSLv3_method +#define SSLv3_server_method yaSSLv3_server_method +#define SSLv3_client_method yaSSLv3_client_method +#define TLSv1_server_method yaTLSv1_server_method +#define TLSv1_client_method yaTLSv1_client_method +#define SSLv23_server_method yaSSLv23_server_method #define SSL_CTX_use_certificate_file yaSSL_CTX_use_certificate_file #define SSL_CTX_use_PrivateKey_file yaSSL_CTX_use_PrivateKey_file #define SSL_CTX_set_cipher_list yaSSL_CTX_set_cipher_list @@ -115,11 +122,13 @@ #define RAND_write_file yaRAND_write_file #define RAND_load_file yaRAND_load_file #define RAND_status yaRAND_status +#define RAND_bytes yaRAND_bytes #define DES_set_key yaDES_set_key #define DES_set_odd_parity yaDES_set_odd_parity #define DES_ecb_encrypt yaDES_ecb_encrypt #define SSL_CTX_set_default_passwd_cb_userdata yaSSL_CTX_set_default_passwd_cb_userdata #define SSL_SESSION_free yaSSL_SESSION_free +#define SSL_peek yaSSL_peek #define SSL_get_certificate yaSSL_get_certificate #define SSL_get_privatekey yaSSL_get_privatekey #define X509_get_pubkey yaX509_get_pubkey diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index 838aace72c8..6e475c23db8 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -626,6 +626,7 @@ struct Connection { bool send_server_key_; // server key exchange? bool master_clean_; // master secret clean? bool TLS_; // TLSv1 or greater + bool sessionID_Set_; // do we have a session ProtocolVersion version_; RandomPool& random_; diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 310e8819c54..98f8035732e 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -1172,7 +1172,8 @@ input_buffer& operator>>(input_buffer& input, ServerHello& hello) // Session hello.id_len_ = input[AUTO]; - input.read(hello.session_id_, ID_LEN); + if (hello.id_len_) + input.read(hello.session_id_, hello.id_len_); // Suites hello.cipher_suite_[0] = input[AUTO]; @@ -1215,7 +1216,10 @@ void ServerHello::Process(input_buffer&, SSL& ssl) { ssl.set_pending(cipher_suite_[1]); ssl.set_random(random_, server_end); + if (id_len_) ssl.set_sessionID(session_id_); + else + ssl.useSecurity().use_connection().sessionID_Set_ = false; if (ssl.getSecurity().get_resuming()) if (memcmp(session_id_, ssl.getSecurity().get_resume().GetID(), diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 831942aaf69..9b83f964348 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -709,6 +709,7 @@ void SSL::set_masterSecret(const opaque* sec) void SSL::set_sessionID(const opaque* sessionID) { memcpy(secure_.use_connection().sessionID_, sessionID, ID_LEN); + secure_.use_connection().sessionID_Set_ = true; } @@ -1423,8 +1424,10 @@ typedef Mutex::Lock Lock; void Sessions::add(const SSL& ssl) { + if (ssl.getSecurity().get_connection().sessionID_Set_) { Lock guard(mutex_); list_.push_back(NEW_YS SSL_SESSION(ssl, random_)); + } } diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt new file mode 100755 index 00000000000..0af0a242e5d --- /dev/null +++ b/extra/yassl/taocrypt/CMakeLists.txt @@ -0,0 +1,10 @@ +INCLUDE_DIRECTORIES(../mySTL include) + +ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp + src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp + src/md4.cpp src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp + include/aes.hpp include/algebra.hpp include/arc4.hpp include/asn.hpp include/block.hpp + include/coding.hpp include/des.hpp include/dh.hpp include/dsa.hpp include/dsa.hpp + include/error.hpp include/file.hpp include/hash.hpp include/hmac.hpp include/integer.hpp + include/md2.hpp include/md5.hpp include/misc.hpp include/modarith.hpp include/modes.hpp + include/random.hpp include/ripemd.hpp include/rsa.hpp include/sha.hpp) diff --git a/extra/yassl/taocrypt/Makefile.am b/extra/yassl/taocrypt/Makefile.am index ac0c1bc29dd..e232b499cc7 100644 --- a/extra/yassl/taocrypt/Makefile.am +++ b/extra/yassl/taocrypt/Makefile.am @@ -1,2 +1,2 @@ SUBDIRS = src test benchmark -EXTRA_DIST = taocrypt.dsw taocrypt.dsp +EXTRA_DIST = taocrypt.dsw taocrypt.dsp CMakeLists.txt diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp index b8095334789..a33ca4fa432 100644 --- a/extra/yassl/taocrypt/src/misc.cpp +++ b/extra/yassl/taocrypt/src/misc.cpp @@ -29,7 +29,7 @@ #include "runtime.hpp" #include "misc.hpp" - +#if !defined(YASSL_MYSQL_COMPATIBLE) extern "C" { // for libcurl configure test, these are the signatures they use @@ -37,6 +37,7 @@ extern "C" { char CRYPTO_lock() { return 0;} char CRYPTO_add_lock() { return 0;} } // extern "C" +#endif #ifdef YASSL_PURE_C diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index c80e3ad23da..482d384d415 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -27,7 +27,7 @@ #endif /* _WIN32 */ -#if !defined(_SOCKLEN_T) && (defined(__MACH__) || defined(_WIN32)) +#if !defined(_SOCKLEN_T) && defined(_WIN32) typedef int socklen_t; #endif diff --git a/heap/CMakeLists.txt b/heap/CMakeLists.txt new file mode 100755 index 00000000000..db5fb8b2981 --- /dev/null +++ b/heap/CMakeLists.txt @@ -0,0 +1,8 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +ADD_LIBRARY(heap _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create.c + hp_delete.c hp_extra.c hp_hash.c hp_info.c hp_open.c hp_panic.c + hp_rename.c hp_rfirst.c hp_rkey.c hp_rlast.c hp_rnext.c hp_rprev.c + hp_rrnd.c hp_rsame.c hp_scan.c hp_static.c hp_update.c hp_write.c) diff --git a/heap/Makefile.am b/heap/Makefile.am index 567c7774751..a89c8a4a878 100644 --- a/heap/Makefile.am +++ b/heap/Makefile.am @@ -28,6 +28,6 @@ libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \ hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \ hp_rkey.c hp_block.c \ hp_hash.c _check.c _rectest.c hp_static.c - +EXTRA_DIST = CMakeLists.txt # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/heap/hp_delete.c b/heap/hp_delete.c index f37db2588f3..f18c5e7054c 100644 --- a/heap/hp_delete.c +++ b/heap/hp_delete.c @@ -73,7 +73,10 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, int res; if (flag) + { info->last_pos= NULL; /* For heap_rnext/heap_rprev */ + info->lastkey_len= 0; + } custom_arg.keyseg= keyinfo->seg; custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); diff --git a/include/config-netware.h b/include/config-netware.h index 5a8b926a669..a3cd6635bae 100644 --- a/include/config-netware.h +++ b/include/config-netware.h @@ -101,6 +101,10 @@ extern "C" { /* On NetWare, to fix the problem with the deletion of open files */ #define CANT_DELETE_OPEN_FILES 1 +#define FN_LIBCHAR '\\' +#define FN_ROOTDIR "\\" +#define FN_DEVCHAR ':' + /* default directory information */ #define DEFAULT_MYSQL_HOME "sys:/mysql" #define PACKAGE "mysql" diff --git a/include/my_dbug.h b/include/my_dbug.h index 6e60b599f53..bf2e8d9969b 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -97,6 +97,7 @@ extern void _db_unlock_file(void); #define DBUG_UNLOCK_FILE #define DBUG_OUTPUT(A) #define DBUG_ASSERT(A) {} +#define DBUG_LEAVE #endif #ifdef __cplusplus } diff --git a/include/mysql.h b/include/mysql.h index 7ed205024e2..ae4a8222c5b 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -165,7 +165,6 @@ struct st_mysql_options { char *ssl_ca; /* PEM CA file */ char *ssl_capath; /* PEM directory of CA-s? */ char *ssl_cipher; /* cipher to use */ - my_bool ssl_verify_server_cert; /* if to verify server cert */ char *shared_memory_base_name; unsigned long max_allowed_packet; my_bool use_ssl; /* if to use SSL or not */ @@ -848,7 +847,6 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); #define stmt_command(mysql, command, arg, length, stmt) \ (*(mysql)->methods->advanced_command)(mysql, command, NullS, \ 0, arg, length, 1, stmt) -unsigned long net_safe_read(MYSQL* mysql); #ifdef __NETWARE__ #pragma pack(pop) /* restore alignment */ diff --git a/include/mysql_com.h b/include/mysql_com.h index ec1c133799f..b1dd6152cf4 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -26,6 +26,9 @@ #define USERNAME_LENGTH 16 #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 +#define SYSTEM_CHARSET_MBMAXLEN 3 +#define NAME_BYTE_LEN NAME_LEN*SYSTEM_CHARSET_MBMAXLEN +#define USERNAME_BYTE_LENGTH USERNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN /* USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain @@ -33,7 +36,7 @@ MySQL standard format: user_name_part@host_name_part\0 */ -#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2 +#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_BYTE_LENGTH + 2 #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." @@ -134,13 +137,14 @@ enum enum_server_command #define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */ #define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */ #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ -#define CLIENT_MULTI_STATEMENTS 65536 /* Enable/disable multi-stmt support */ -#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */ +#define CLIENT_MULTI_STATEMENTS (((ulong) 1) << 16) /* Enable/disable multi-stmt support */ +#define CLIENT_MULTI_RESULTS (((ulong) 1) << 17) /* Enable/disable multi-results */ + +#define CLIENT_SSL_VERIFY_SERVER_CERT (((ulong) 1) << 30) #define CLIENT_REMEMBER_OPTIONS (((ulong) 1) << 31) #define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ -#define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */ #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ #define SERVER_QUERY_NO_GOOD_INDEX_USED 16 #define SERVER_QUERY_NO_INDEX_USED 32 @@ -210,7 +214,13 @@ typedef struct st_net { char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1]; unsigned int last_errno; unsigned char error; + + /* + 'query_cache_query' should be accessed only via query cache + functions and methods to maintain proper locking. + */ gptr query_cache_query; + my_bool report_error; /* We should report error (we have unreported error) */ my_bool return_errno; } NET; diff --git a/include/sql_common.h b/include/sql_common.h index 7ea8b6c87e0..29a9cbd4b08 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -36,7 +36,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, const char *header, ulong header_length, const char *arg, ulong arg_length, my_bool skip_check, MYSQL_STMT *stmt); - +unsigned long cli_safe_read(MYSQL *mysql); void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, const char *sqlstate); void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate); diff --git a/innobase/CMakeLists.txt b/innobase/CMakeLists.txt new file mode 100755 index 00000000000..f9661963d56 --- /dev/null +++ b/innobase/CMakeLists.txt @@ -0,0 +1,35 @@ +#SET(CMAKE_CXX_FLAGS_DEBUG "-DSAFEMALLOC -DSAFE_MUTEX") +#SET(CMAKE_C_FLAGS_DEBUG "-DSAFEMALLOC -DSAFE_MUTEX") +ADD_DEFINITIONS(-DMYSQL_SERVER -D_WIN32 -DWIN32 -D_LIB) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include include) +ADD_LIBRARY(innobase btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c + buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c + data/data0data.c data/data0type.c + dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c + dyn/dyn0dyn.c + eval/eval0eval.c eval/eval0proc.c + fil/fil0fil.c + fsp/fsp0fsp.c + fut/fut0fut.c fut/fut0lst.c + ha/ha0ha.c ha/hash0hash.c + ibuf/ibuf0ibuf.c + pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c + lock/lock0lock.c + log/log0log.c log/log0recv.c + mach/mach0data.c + mem/mem0mem.c mem/mem0pool.c + mtr/mtr0log.c mtr/mtr0mtr.c + os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c + page/page0cur.c page/page0page.c + que/que0que.c + read/read0read.c + rem/rem0cmp.c rem/rem0rec.c + row/row0ins.c row/row0mysql.c row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c + row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c + srv/srv0que.c srv/srv0srv.c srv/srv0start.c + sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c + thr/thr0loc.c + trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c + usr/usr0sess.c + ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ) diff --git a/innobase/Makefile.am b/innobase/Makefile.am index 8ff90d16a2c..10e793396d8 100644 --- a/innobase/Makefile.am +++ b/innobase/Makefile.am @@ -25,6 +25,7 @@ noinst_HEADERS = ib_config.h SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \ ha ibuf include lock log mach mem mtr page \ pars que read rem row srv sync thr trx usr +EXTRA_DIST = CMakeLists.txt # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index c27fb73ff8d..07bc04feae6 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -616,7 +616,7 @@ btr_page_get_father_for_rec( fputs( "InnoDB: You should dump + drop + reimport the table to fix the\n" "InnoDB: corruption. If the crash happens at the database startup, see\n" -"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html about\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html about\n" "InnoDB: forcing recovery. Then dump + drop + reimport.\n", stderr); } diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index 99509a89de0..db09a931c29 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -323,7 +323,8 @@ buf_page_is_corrupted( "InnoDB: is in the future! Current system log sequence number %lu %lu.\n" "InnoDB: Your database may be corrupt or you may have copied the InnoDB\n" "InnoDB: tablespace but not the InnoDB log files. See\n" -"http://dev.mysql.com/doc/mysql/en/backing-up.html for more information.\n", +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" +"InnoDB: for more information.\n", (ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET), (ulong) ut_dulint_get_high( mach_read_from_8(read_buf + FIL_PAGE_LSN)), @@ -1867,7 +1868,7 @@ buf_page_io_complete( "InnoDB: the corrupt table. You can use CHECK\n" "InnoDB: TABLE to scan your table for corruption.\n" "InnoDB: See also " - "http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index bad8886d0be..fffe851bc52 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2228,8 +2228,8 @@ dict_foreign_error_report( if (fk->foreign_index) { fputs("The index in the foreign key in table is ", file); ut_print_name(file, NULL, fk->foreign_index->name); - fputs( -"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" + fputs("\n" +"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n" "for correct foreign key definition.\n", file); } @@ -3131,7 +3131,7 @@ col_loop1: ut_print_name(ef, NULL, name); fprintf(ef, " where the columns appear\n" "as the first columns. Constraint:\n%s\n" -"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" +"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n" "for correct foreign key definition.\n", start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -3399,7 +3399,7 @@ try_find_index: "Note that the internal storage type of ENUM and SET changed in\n" "tables created with >= InnoDB-4.1.12, and such columns in old tables\n" "cannot be referenced by such columns in new tables.\n" -"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" +"See http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html\n" "for correct foreign key definition.\n", start_of_latest_foreign); mutex_exit(&dict_foreign_err_mutex); @@ -4059,8 +4059,7 @@ dict_update_statistics_low( fprintf(stderr, " InnoDB: cannot calculate statistics for table %s\n" "InnoDB: because the .ibd file is missing. For help, please refer to\n" -"InnoDB: " -"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n", +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", table->name); return; diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 2272f7cd8b3..64987294654 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -2689,8 +2689,7 @@ fil_open_single_table_tablespace( "InnoDB: It is also possible that this is a temporary table #sql...,\n" "InnoDB: and MySQL removed the .ibd file for this.\n" "InnoDB: Please refer to\n" -"InnoDB:" -" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: for how to resolve the issue.\n", stderr); mem_free(filepath); @@ -2729,8 +2728,7 @@ fil_open_single_table_tablespace( "InnoDB: Have you moved InnoDB .ibd files around without using the\n" "InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n" "InnoDB: Please refer to\n" -"InnoDB:" -" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: for how to resolve the issue.\n", (ulong) space_id, (ulong) id); ret = FALSE; @@ -3375,8 +3373,7 @@ fil_space_for_table_exists_in_mem( error_exit: fputs( "InnoDB: Please refer to\n" -"InnoDB:" -" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: for how to resolve the issue.\n", stderr); mem_free(path); diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index ad4228f6797..333894d2312 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -2975,7 +2975,7 @@ fseg_free_page_low( crash: fputs( "InnoDB: Please refer to\n" -"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_error; } diff --git a/innobase/include/btr0cur.ic b/innobase/include/btr0cur.ic index bf8a6efb68d..dcad3e9e14d 100644 --- a/innobase/include/btr0cur.ic +++ b/innobase/include/btr0cur.ic @@ -52,9 +52,7 @@ btr_cur_get_page( /* out: pointer to page */ btr_cur_t* cursor) /* in: tree cursor */ { - page_t* page = buf_frame_align(page_cur_get_rec(&(cursor->page_cur))); - ut_ad(!!page_is_comp(page) == cursor->index->table->comp); - return(page); + return(buf_frame_align(page_cur_get_rec(&(cursor->page_cur)))); } /************************************************************* diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index d949254d47d..af32db10b5f 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -215,8 +215,8 @@ buf_block_align( "InnoDB: Error: trying to access a stray pointer %p\n" "InnoDB: buf pool start is at %p, end at %p\n" "InnoDB: Probable reason is database corruption or memory\n" -"InnoDB: corruption. If this happens in an InnoDB database recovery,\n" -"InnoDB: you can look from section 6.1 at http://www.innodb.com/ibman.html\n" +"InnoDB: corruption. If this happens in an InnoDB database recovery, see\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" "InnoDB: how to force recovery.\n", ptr, frame_zero, buf_pool->high_end); @@ -251,8 +251,8 @@ buf_frame_align( "InnoDB: Error: trying to access a stray pointer %p\n" "InnoDB: buf pool start is at %p, end at %p\n" "InnoDB: Probable reason is database corruption or memory\n" -"InnoDB: corruption. If this happens in an InnoDB database recovery,\n" -"InnoDB: you can look from section 6.1 at http://www.innodb.com/ibman.html\n" +"InnoDB: corruption. If this happens in an InnoDB database recovery, see\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" "InnoDB: how to force recovery.\n", ptr, buf_pool->frame_zero, buf_pool->high_end); diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 2f76bf450db..2d3bff522e2 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -720,7 +720,7 @@ failure: "InnoDB: To get mysqld to start up, set innodb_thread_concurrency in my.cnf\n" "InnoDB: to a lower value, for example, to 8. After an ERROR-FREE shutdown\n" "InnoDB: of mysqld you can adjust the size of ib_logfiles, as explained in\n" -"InnoDB: http://dev.mysql.com/doc/mysql/en/Adding_and_removing.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/adding-and-removing.html\n" "InnoDB: Cannot continue operation. Calling exit(1).\n", (ulong)srv_thread_concurrency); diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 7c56fe35d48..113d237b535 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -543,7 +543,7 @@ recv_find_max_checkpoint( "InnoDB: the problem may be that during an earlier attempt you managed\n" "InnoDB: to create the InnoDB data files, but log file creation failed.\n" "InnoDB: If that is the case, please refer to\n" -"InnoDB: http://dev.mysql.com/doc/mysql/en/Error_creating_InnoDB.html\n"); +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/error-creating-innodb.html\n"); return(DB_ERROR); } @@ -1954,7 +1954,7 @@ recv_report_corrupt_log( "InnoDB: far enough in recovery! Please run CHECK TABLE\n" "InnoDB: on your InnoDB tables to check that they are ok!\n" "InnoDB: If mysqld crashes after this recovery, look at\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n" + "InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); fflush(stderr); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index df819b73ea6..075005c3611 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -248,7 +248,7 @@ os_file_get_last_error( fprintf(stderr, "InnoDB: Some operating system error numbers are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n"); + "http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n"); } } @@ -295,7 +295,7 @@ os_file_get_last_error( fprintf(stderr, "InnoDB: Some operating system error numbers are described at\n" "InnoDB: " - "http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n"); + "http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n"); } } @@ -709,7 +709,7 @@ next_file: /* TODO: test Windows symlinks */ /* TODO: MySQL has apparently its own symlink implementation in Windows, dbname.sym can redirect a database directory: -http://www.mysql.com/doc/en/Windows_symbolic_links.html */ +http://dev.mysql.com/doc/refman/5.0/en/windows-symbolic-links.html */ info->type = OS_FILE_TYPE_LINK; } else if (lpFindFileData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { @@ -2364,7 +2364,7 @@ retry: "InnoDB: offset %lu %lu. Operating system error number %lu.\n" "InnoDB: Some operating system error numbers are described at\n" "InnoDB: " -"http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n", +"http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n", name, (ulong) offset_high, (ulong) offset, (ulong) GetLastError()); @@ -2429,7 +2429,7 @@ retry: fprintf(stderr, "InnoDB: Some operating system error numbers are described at\n" "InnoDB: " -"http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n"); +"http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n"); os_has_said_disk_full = TRUE; } @@ -2465,7 +2465,7 @@ retry: fprintf(stderr, "InnoDB: Some operating system error numbers are described at\n" "InnoDB: " -"http://dev.mysql.com/doc/mysql/en/Operating_System_error_codes.html\n"); +"http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html\n"); os_has_said_disk_full = TRUE; } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 9e922a3e04a..955c7139de7 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -547,7 +547,7 @@ handle_new_error: "InnoDB: tables and recreate the whole InnoDB tablespace.\n" "InnoDB: If the mysqld server crashes after the startup or when\n" "InnoDB: you dump the tables, look at\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html" + "InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html" " for help.\n", stderr); } else { @@ -1077,7 +1077,7 @@ row_insert_for_mysql( "InnoDB: Have you deleted the .ibd file from the database directory under\n" "InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" -"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); return(DB_ERROR); @@ -1312,7 +1312,7 @@ row_update_for_mysql( "InnoDB: Have you deleted the .ibd file from the database directory under\n" "InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" -"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); return(DB_ERROR); @@ -1964,8 +1964,8 @@ row_create_table_for_mysql( "InnoDB: Then MySQL thinks the table exists, and DROP TABLE will\n" "InnoDB: succeed.\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/" - "InnoDB_troubleshooting_datadict.html\n", stderr); +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", + stderr); } /* We may also get err == DB_ERROR if the .ibd file for the @@ -3207,8 +3207,8 @@ row_drop_table_for_mysql( "InnoDB: Have you copied the .frm file of the table to the\n" "InnoDB: MySQL database directory from another database?\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/" - "InnoDB_troubleshooting_datadict.html\n", stderr); +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", + stderr); goto funct_exit; } @@ -3675,8 +3675,8 @@ row_rename_table_for_mysql( "InnoDB: Have you copied the .frm file of the table to the\n" "InnoDB: MySQL database directory from another database?\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/" - "InnoDB_troubleshooting_datadict.html\n", stderr); +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", + stderr); goto funct_exit; } @@ -3689,8 +3689,8 @@ row_rename_table_for_mysql( fputs( " does not have an .ibd file in the database directory.\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/" - "InnoDB_troubleshooting_datadict.html\n", stderr); +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", + stderr); goto funct_exit; } @@ -3829,8 +3829,7 @@ row_rename_table_for_mysql( fputs(" to it.\n" "InnoDB: Have you deleted the .frm file and not used DROP TABLE?\n" "InnoDB: You can look for further help from\n" - "InnoDB: http://dev.mysql.com/doc/mysql/en/" - "InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: If table ", stderr); ut_print_name(stderr, trx, new_name); fputs( @@ -4081,7 +4080,7 @@ row_check_table_for_mysql( "InnoDB: Have you deleted the .ibd file from the database directory under\n" "InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" -"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); return(DB_ERROR); diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 23971767e7e..ec56afbb4f5 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -3101,7 +3101,7 @@ row_search_for_mysql( "InnoDB: Have you deleted the .ibd file from the database directory under\n" "InnoDB: the MySQL datadir, or have you used DISCARD TABLESPACE?\n" "InnoDB: Look from\n" -"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "InnoDB: how you can resolve the problem.\n", prebuilt->table->name); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index b345a27af20..6e0dc720bf8 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1715,7 +1715,7 @@ NetWare. */ "InnoDB: You have now successfully upgraded to the multiple tablespaces\n" "InnoDB: format. You should NOT DOWNGRADE to an earlier version of\n" "InnoDB: InnoDB! But if you absolutely need to downgrade, see\n" -"InnoDB: http://dev.mysql.com/doc/mysql/en/Multiple_tablespaces.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/multiple-tablespaces.html\n" "InnoDB: for instructions.\n"); } diff --git a/innobase/ut/ut0dbg.c b/innobase/ut/ut0dbg.c index e810d8dead7..8b284e47286 100644 --- a/innobase/ut/ut0dbg.c +++ b/innobase/ut/ut0dbg.c @@ -54,7 +54,7 @@ ut_dbg_assertion_failed( "InnoDB: If you get repeated assertion failures or crashes, even\n" "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. Please refer to\n" -"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n" +"InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_dbg_stop_threads = TRUE; } diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt new file mode 100755 index 00000000000..d12b6ca6c10 --- /dev/null +++ b/libmysql/CMakeLists.txt @@ -0,0 +1,54 @@ +# Need to set USE_TLS, since __declspec(thread) approach to thread local +# storage does not work properly in DLLs. +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/libmysql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/strings) + +ADD_LIBRARY(libmysql SHARED dll.c libmysql.def + ../mysys/array.c ../strings/bchange.c ../strings/bmove.c + ../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c + ../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c + ../strings/ctype-cp932.c ../strings/ctype-czech.c ../strings/ctype-euc_kr.c + ../strings/ctype-eucjpms.c ../strings/ctype-extra.c ../strings/ctype-gb2312.c + ../strings/ctype-gbk.c ../strings/ctype-latin1.c ../strings/ctype-mb.c + ../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c + ../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c + ../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c + ../mysys/default.c ../libmysql/errmsg.c ../mysys/errors.c + ../libmysql/get_password.c ../strings/int2str.c ../strings/is_prefix.c + ../libmysql/libmysql.c ../mysys/list.c ../strings/llstr.c + ../strings/longlong2str.c ../libmysql/manager.c ../mysys/mf_cache.c + ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c + ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c + ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c + ../mysys/mf_wcomp.c ../mysys/mulalloc.c ../mysys/my_access.c ../mysys/my_alloc.c + ../mysys/my_chsize.c ../mysys/my_compress.c ../mysys/my_create.c + ../mysys/my_delete.c ../mysys/my_div.c ../mysys/my_error.c ../mysys/my_file.c + ../mysys/my_fopen.c ../mysys/my_fstream.c ../mysys/my_gethostbyname.c + ../mysys/my_getopt.c ../mysys/my_getwd.c ../mysys/my_init.c ../mysys/my_lib.c + ../mysys/my_malloc.c ../mysys/my_messnc.c ../mysys/my_net.c ../mysys/my_once.c + ../mysys/my_open.c ../mysys/my_pread.c ../mysys/my_pthread.c ../mysys/my_read.c + ../mysys/my_realloc.c ../mysys/my_rename.c ../mysys/my_seek.c + ../mysys/my_static.c ../strings/my_strtoll10.c ../mysys/my_symlink.c + ../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c + ../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c + ../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c + ../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c + ../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c + ../strings/strfill.c ../mysys/string.c ../strings/strinstr.c ../strings/strmake.c + ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c + ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c + ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c + ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c) +ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt) +TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32) + +ADD_EXECUTABLE(myTest mytest.c) +TARGET_LINK_LIBRARIES(myTest libmysql) diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am index d089d56f38a..5e6c60a007b 100644 --- a/libmysql/Makefile.am +++ b/libmysql/Makefile.am @@ -31,7 +31,7 @@ include $(srcdir)/Makefile.shared libmysqlclient_la_SOURCES = $(target_sources) libmysqlclient_la_LIBADD = $(target_libadd) $(yassl_las) libmysqlclient_la_LDFLAGS = $(target_ldflags) -EXTRA_DIST = Makefile.shared libmysql.def +EXTRA_DIST = Makefile.shared libmysql.def dll.c mytest.c CMakeLists.txt noinst_HEADERS = client_settings.h # This is called from the toplevel makefile diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 4efc3c2fd1c..21fb84fb19a 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -645,7 +645,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) NET *net= &mysql->net; ulong pkt_length; - pkt_length= net_safe_read(mysql); + pkt_length= cli_safe_read(mysql); if (pkt_length == packet_error) return 1; @@ -666,7 +666,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) return 1; } /* Read what server thinks about out new auth message report */ - if (net_safe_read(mysql) == packet_error) + if (cli_safe_read(mysql) == packet_error) return 1; } return 0; @@ -1887,7 +1887,7 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) DBUG_ENTER("cli_read_prepare_result"); mysql= mysql->last_used_con; - if ((packet_length= net_safe_read(mysql)) == packet_error) + if ((packet_length= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); mysql->warning_count= 0; @@ -2505,7 +2505,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt) if (stmt->param_count) { - NET *net= &stmt->mysql->net; + MYSQL *mysql= stmt->mysql; + NET *net= &mysql->net; MYSQL_BIND *param, *param_end; char *param_data; ulong length; @@ -2517,7 +2518,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt) set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate); DBUG_RETURN(1); } - if (stmt->mysql->status != MYSQL_STATUS_READY) + if (mysql->status != MYSQL_STATUS_READY || + mysql->server_status & SERVER_MORE_RESULTS_EXISTS) { set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); DBUG_RETURN(1); @@ -4532,7 +4534,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) int cli_unbuffered_fetch(MYSQL *mysql, char **row) { - if (packet_error == net_safe_read(mysql)) + if (packet_error == cli_safe_read(mysql)) return 1; *row= ((mysql->net.read_pos[0] == 254) ? NULL : @@ -4641,7 +4643,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) mysql= mysql->last_used_con; - while ((pkt_len= net_safe_read(mysql)) != packet_error) + while ((pkt_len= cli_safe_read(mysql)) != packet_error) { cp= net->read_pos; if (cp[0] != 254 || pkt_len >= 8) diff --git a/libmysql/mytest.c b/libmysql/mytest.c new file mode 100644 index 00000000000..2d5c576b72a --- /dev/null +++ b/libmysql/mytest.c @@ -0,0 +1,175 @@ +/*C4*/ +/****************************************************************/ +/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */ +/* Date: 02/18/1998 */ +/* mytest.c : do some testing of the libmySQL.DLL.... */ +/* */ +/* History: */ +/* 02/18/1998 jw3 also sprach zarathustra.... */ +/****************************************************************/ + + +#include <windows.h> +#include <stdio.h> +#include <string.h> + +#include <mysql.h> + +#define DEFALT_SQL_STMT "SELECT * FROM db" +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + + +/******************************************************** +** +** main :- +** +********************************************************/ + +int +main( int argc, char * argv[] ) +{ + + char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ; + const char *pszT; + int i, j, k, l, x ; + MYSQL * myData ; + MYSQL_RES * res ; + MYSQL_FIELD * fd ; + MYSQL_ROW row ; + + //....just curious.... + printf( "sizeof( MYSQL ) == %d\n", (int) sizeof( MYSQL ) ) ; + if ( argc == 2 ) + { + strcpy( szDB, argv[ 1 ] ) ; + strcpy( szSQL, DEFALT_SQL_STMT ) ; + if (!strcmp(szDB,"--debug")) + { + strcpy( szDB, "mysql" ) ; + printf("Some mysql struct information (size and offset):\n"); + printf("net:\t%3d %3d\n",(int) sizeof(myData->net), + (int) offsetof(MYSQL,net)); + printf("host:\t%3d %3d\n",(int) sizeof(myData->host), + (int) offsetof(MYSQL,host)); + printf("port:\t%3d %3d\n", (int) sizeof(myData->port), + (int) offsetof(MYSQL,port)); + printf("protocol_version:\t%3d %3d\n", + (int) sizeof(myData->protocol_version), + (int) offsetof(MYSQL,protocol_version)); + printf("thread_id:\t%3d %3d\n",(int) sizeof(myData->thread_id), + (int) offsetof(MYSQL,thread_id)); + printf("affected_rows:\t%3d %3d\n",(int) sizeof(myData->affected_rows), + (int) offsetof(MYSQL,affected_rows)); + printf("packet_length:\t%3d %3d\n",(int) sizeof(myData->packet_length), + (int) offsetof(MYSQL,packet_length)); + printf("status:\t%3d %3d\n",(int) sizeof(myData->status), + (int) offsetof(MYSQL,status)); + printf("fields:\t%3d %3d\n",(int) sizeof(myData->fields), + (int) offsetof(MYSQL,fields)); + printf("field_alloc:\t%3d %3d\n",(int) sizeof(myData->field_alloc), + (int) offsetof(MYSQL,field_alloc)); + printf("free_me:\t%3d %3d\n",(int) sizeof(myData->free_me), + (int) offsetof(MYSQL,free_me)); + printf("options:\t%3d %3d\n",(int) sizeof(myData->options), + (int) offsetof(MYSQL,options)); + puts(""); + } + } + else if ( argc > 2 ) { + strcpy( szDB, argv[ 1 ] ) ; + strcpy( szSQL, argv[ 2 ] ) ; + } + else { + strcpy( szDB, "mysql" ) ; + strcpy( szSQL, DEFALT_SQL_STMT ) ; + } + //.... + + if ( (myData = mysql_init((MYSQL*) 0)) && + mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT, + NULL, 0 ) ) + { + myData->reconnect= 1; + if ( mysql_select_db( myData, szDB ) < 0 ) { + printf( "Can't select the %s database !\n", szDB ) ; + mysql_close( myData ) ; + return 2 ; + } + } + else { + printf( "Can't connect to the mysql server on port %d !\n", + MYSQL_PORT ) ; + mysql_close( myData ) ; + return 1 ; + } + //.... + if ( ! mysql_query( myData, szSQL ) ) { + res = mysql_store_result( myData ) ; + i = (int) mysql_num_rows( res ) ; l = 1 ; + printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ; + //....we can get the field-specific characteristics here.... + for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) + strcpy( aszFlds[ x ], fd->name ) ; + //.... + while ( row = mysql_fetch_row( res ) ) { + j = mysql_num_fields( res ) ; + printf( "Record #%ld:-\n", l++ ) ; + for ( k = 0 ; k < j ; k++ ) + printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], + (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; + puts( "==============================\n" ) ; + } + mysql_free_result( res ) ; + } + else printf( "Couldn't execute %s on the server !\n", szSQL ) ; + //.... + puts( "==== Diagnostic info ====" ) ; + pszT = mysql_get_client_info() ; + printf( "Client info: %s\n", pszT ) ; + //.... + pszT = mysql_get_host_info( myData ) ; + printf( "Host info: %s\n", pszT ) ; + //.... + pszT = mysql_get_server_info( myData ) ; + printf( "Server info: %s\n", pszT ) ; + //.... + res = mysql_list_processes( myData ) ; l = 1 ; + if (res) + { + for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) + strcpy( aszFlds[ x ], fd->name ) ; + while ( row = mysql_fetch_row( res ) ) { + j = mysql_num_fields( res ) ; + printf( "Process #%ld:-\n", l++ ) ; + for ( k = 0 ; k < j ; k++ ) + printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], + (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; + puts( "==============================\n" ) ; + } + } + else + { + printf("Got error %s when retreiving processlist\n",mysql_error(myData)); + } + //.... + res = mysql_list_tables( myData, "%" ) ; l = 1 ; + for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) + strcpy( aszFlds[ x ], fd->name ) ; + while ( row = mysql_fetch_row( res ) ) { + j = mysql_num_fields( res ) ; + printf( "Table #%ld:-\n", l++ ) ; + for ( k = 0 ; k < j ; k++ ) + printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], + (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; + puts( "==============================\n" ) ; + } + //.... + pszT = mysql_stat( myData ) ; + puts( pszT ) ; + //.... + mysql_close( myData ) ; + return 0 ; + +} diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 3895588e02c..0e80681700f 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -163,3 +163,4 @@ EXPORTS my_charset_bin my_charset_same modify_defaults_file + mysql_set_server_option diff --git a/myisam/CMakeLists.txt b/myisam/CMakeLists.txt new file mode 100755 index 00000000000..3ba7aba4555 --- /dev/null +++ b/myisam/CMakeLists.txt @@ -0,0 +1,26 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +ADD_LIBRARY(myisam ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c ft_stem.c + ft_stopwords.c ft_update.c mi_cache.c mi_changed.c mi_check.c + mi_checksum.c mi_close.c mi_create.c mi_dbug.c mi_delete.c + mi_delete_all.c mi_delete_table.c mi_dynrec.c mi_extra.c mi_info.c + mi_key.c mi_keycache.c mi_locking.c mi_log.c mi_open.c + mi_packrec.c mi_page.c mi_panic.c mi_preload.c mi_range.c mi_rename.c + mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c + mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c + mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c + rt_split.c sort.c sp_key.c ft_eval.h myisamdef.h rt_index.h mi_rkey.c) + +ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c) +TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys dbug strings zlib wsock32) + +ADD_EXECUTABLE(myisamchk myisamchk.c) +TARGET_LINK_LIBRARIES(myisamchk myisam mysys dbug strings zlib wsock32) + +ADD_EXECUTABLE(myisamlog myisamlog.c) +TARGET_LINK_LIBRARIES(myisamlog myisam mysys dbug strings zlib wsock32) + +ADD_EXECUTABLE(myisampack myisampack.c) +TARGET_LINK_LIBRARIES(myisampack myisam mysys dbug strings zlib wsock32) diff --git a/myisam/Makefile.am b/myisam/Makefile.am index e4327070997..081d7facf3a 100644 --- a/myisam/Makefile.am +++ b/myisam/Makefile.am @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -EXTRA_DIST = mi_test_all.sh mi_test_all.res +EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt pkgdata_DATA = mi_test_all mi_test_all.res INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index bc0389980b9..ef5ab73f1a9 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -1130,12 +1130,41 @@ void _my_store_blob_length(byte *pos,uint pack_length,uint length) } - /* Read record from datafile */ - /* Returns 0 if ok, -1 if error */ +/* + Read record from datafile. + + SYNOPSIS + _mi_read_dynamic_record() + info MI_INFO pointer to table. + filepos From where to read the record. + buf Destination for record. + + NOTE + + If a write buffer is active, it needs to be flushed if its contents + intersects with the record to read. We always check if the position + of the first byte of the write buffer is lower than the position + past the last byte to read. In theory this is also true if the write + buffer is completely below the read segment. That is, if there is no + intersection. But this case is unusual. We flush anyway. Only if the + first byte in the write buffer is above the last byte to read, we do + not flush. + + A dynamic record may need several reads. So this check must be done + before every read. Reading a dynamic record starts with reading the + block header. If the record does not fit into the free space of the + header, the block may be longer than the header. In this case a + second read is necessary. These one or two reads repeat for every + part of the record. + + RETURN + 0 OK + -1 Error +*/ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) { - int flag; + int block_of_record; uint b_type,left_length; byte *to; MI_BLOCK_INFO block_info; @@ -1147,20 +1176,19 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) LINT_INIT(to); LINT_INIT(left_length); file=info->dfile; - block_info.next_filepos=filepos; /* for easyer loop */ - flag=block_info.second_read=0; + block_of_record= 0; /* First block of record is numbered as zero. */ + block_info.second_read= 0; do { + /* A corrupted table can have wrong pointers. (Bug# 19835) */ + if (filepos == HA_OFFSET_ERROR) + goto panic; if (info->opt_flag & WRITE_CACHE_USED && - info->rec_cache.pos_in_file <= block_info.next_filepos && + info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH && flush_io_cache(&info->rec_cache)) goto err; - /* A corrupted table can have wrong pointers. (Bug# 19835) */ - if (block_info.next_filepos == HA_OFFSET_ERROR) - goto panic; info->rec_cache.seek_not_done=1; - if ((b_type=_mi_get_block_info(&block_info,file, - block_info.next_filepos)) + if ((b_type= _mi_get_block_info(&block_info, file, filepos)) & (BLOCK_DELETED | BLOCK_ERROR | BLOCK_SYNC_ERROR | BLOCK_FATAL_ERROR)) { @@ -1168,9 +1196,8 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) my_errno=HA_ERR_RECORD_DELETED; goto err; } - if (flag == 0) /* First block */ + if (block_of_record++ == 0) /* First block */ { - flag=1; if (block_info.rec_len > (uint) info->s->base.max_pack_length) goto panic; if (info->s->base.blobs) @@ -1185,11 +1212,35 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf) } if (left_length < block_info.data_len || ! block_info.data_len) goto panic; /* Wrong linked record */ - if (my_pread(file,(byte*) to,block_info.data_len,block_info.filepos, - MYF(MY_NABP))) - goto panic; - left_length-=block_info.data_len; - to+=block_info.data_len; + /* copy information that is already read */ + { + uint offset= (uint) (block_info.filepos - filepos); + uint prefetch_len= (sizeof(block_info.header) - offset); + filepos+= sizeof(block_info.header); + + if (prefetch_len > block_info.data_len) + prefetch_len= block_info.data_len; + if (prefetch_len) + { + memcpy((byte*) to, block_info.header + offset, prefetch_len); + block_info.data_len-= prefetch_len; + left_length-= prefetch_len; + to+= prefetch_len; + } + } + /* read rest of record from file */ + if (block_info.data_len) + { + if (info->opt_flag & WRITE_CACHE_USED && + info->rec_cache.pos_in_file < filepos + block_info.data_len && + flush_io_cache(&info->rec_cache)) + goto err; + if (my_read(file, (byte*) to, block_info.data_len, MYF(MY_NABP))) + goto panic; + left_length-=block_info.data_len; + to+=block_info.data_len; + } + filepos= block_info.next_filepos; } while (left_length); info->update|= HA_STATE_AKTIV; /* We have a aktive record */ @@ -1346,11 +1397,45 @@ err: } +/* + Read record from datafile. + + SYNOPSIS + _mi_read_rnd_dynamic_record() + info MI_INFO pointer to table. + buf Destination for record. + filepos From where to read the record. + skip_deleted_blocks If to repeat reading until a non-deleted + record is found. + + NOTE + + If a write buffer is active, it needs to be flushed if its contents + intersects with the record to read. We always check if the position + of the first byte of the write buffer is lower than the position + past the last byte to read. In theory this is also true if the write + buffer is completely below the read segment. That is, if there is no + intersection. But this case is unusual. We flush anyway. Only if the + first byte in the write buffer is above the last byte to read, we do + not flush. + + A dynamic record may need several reads. So this check must be done + before every read. Reading a dynamic record starts with reading the + block header. If the record does not fit into the free space of the + header, the block may be longer than the header. In this case a + second read is necessary. These one or two reads repeat for every + part of the record. + + RETURN + 0 OK + != 0 Error +*/ + int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, register my_off_t filepos, my_bool skip_deleted_blocks) { - int flag,info_read,save_errno; + int block_of_record, info_read, save_errno; uint left_len,b_type; byte *to; MI_BLOCK_INFO block_info; @@ -1376,7 +1461,8 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, else info_read=1; /* memory-keyinfoblock is ok */ - flag=block_info.second_read=0; + block_of_record= 0; /* First block of record is numbered as zero. */ + block_info.second_read= 0; left_len=1; do { @@ -1399,15 +1485,15 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, { if (_mi_read_cache(&info->rec_cache,(byte*) block_info.header,filepos, sizeof(block_info.header), - (!flag && skip_deleted_blocks ? READING_NEXT : 0) | - READING_HEADER)) + (!block_of_record && skip_deleted_blocks ? + READING_NEXT : 0) | READING_HEADER)) goto panic; b_type=_mi_get_block_info(&block_info,-1,filepos); } else { if (info->opt_flag & WRITE_CACHE_USED && - info->rec_cache.pos_in_file <= filepos && + info->rec_cache.pos_in_file < filepos + MI_BLOCK_INFO_HEADER_LENGTH && flush_io_cache(&info->rec_cache)) DBUG_RETURN(my_errno); info->rec_cache.seek_not_done=1; @@ -1432,7 +1518,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, } goto err; } - if (flag == 0) /* First block */ + if (block_of_record == 0) /* First block */ { if (block_info.rec_len > (uint) share->base.max_pack_length) goto panic; @@ -1465,7 +1551,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, left_len-=tmp_length; to+=tmp_length; filepos+=tmp_length; - } + } } /* read rest of record from file */ if (block_info.data_len) @@ -1474,11 +1560,17 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, { if (_mi_read_cache(&info->rec_cache,(byte*) to,filepos, block_info.data_len, - (!flag && skip_deleted_blocks) ? READING_NEXT :0)) + (!block_of_record && skip_deleted_blocks) ? + READING_NEXT : 0)) goto panic; } else { + if (info->opt_flag & WRITE_CACHE_USED && + info->rec_cache.pos_in_file < + block_info.filepos + block_info.data_len && + flush_io_cache(&info->rec_cache)) + goto err; /* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */ if (my_read(info->dfile,(byte*) to,block_info.data_len,MYF(MY_NABP))) { @@ -1488,10 +1580,14 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf, } } } - if (flag++ == 0) + /* + Increment block-of-record counter. If it was the first block, + remember the position behind the block for the next call. + */ + if (block_of_record++ == 0) { - info->nextpos=block_info.filepos+block_info.block_len; - skip_deleted_blocks=0; + info->nextpos= block_info.filepos + block_info.block_len; + skip_deleted_blocks= 0; } left_len-=block_info.data_len; to+=block_info.data_len; @@ -1523,6 +1619,11 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos) if (file >= 0) { + /* + We do not use my_pread() here because we want to have the file + pointer set to the end of the header after this function. + my_pread() may leave the file pointer untouched. + */ VOID(my_seek(file,filepos,MY_SEEK_SET,MYF(0))); if (my_read(file,(char*) header,sizeof(info->header),MYF(0)) != sizeof(info->header)) diff --git a/myisam/mi_update.c b/myisam/mi_update.c index f8b5cf55406..9ddda3f5ea9 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -172,7 +172,17 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | key_changed); myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0); - VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0)); + /* + Every myisam function that updates myisam table must end with + call to _mi_writeinfo(). If operation (second param of + _mi_writeinfo()) is not 0 it sets share->changed to 1, that is + flags that data has changed. If operation is 0, this function + equals to no-op in this case. + + mi_update() must always pass !0 value as operation, since even if + there is no index change there could be data change. + */ + VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE)); allow_break(); /* Allow SIGHUP & SIGINT */ if (info->invalidator != 0) { diff --git a/myisam/sort.c b/myisam/sort.c index c9562461f56..00fbfe768dc 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -483,13 +483,6 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) if (!got_error) { mi_set_key_active(share->state.key_map, sinfo->key); - if (param->testflag & T_STATISTICS) - update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique, - param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? - sinfo->notnull: NULL, - (ulonglong) info->state->records); - - if (!sinfo->buffpek.elements) { if (param->testflag & T_VERBOSE) @@ -501,6 +494,11 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) flush_ft_buf(sinfo) || flush_pending_blocks(sinfo)) got_error=1; } + if (!got_error && param->testflag & T_STATISTICS) + update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique, + param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? + sinfo->notnull: NULL, + (ulonglong) info->state->records); } my_free((gptr) sinfo->sort_keys,MYF(0)); my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff), diff --git a/myisammrg/CMakeLists.txt b/myisammrg/CMakeLists.txt new file mode 100755 index 00000000000..83168f6c60c --- /dev/null +++ b/myisammrg/CMakeLists.txt @@ -0,0 +1,9 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +ADD_LIBRARY(myisammrg myrg_close.c myrg_create.c myrg_delete.c myrg_extra.c myrg_info.c + myrg_locking.c myrg_open.c myrg_panic.c myrg_queue.c myrg_range.c + myrg_rfirst.c myrg_rkey.c myrg_rlast.c myrg_rnext.c myrg_rnext_same.c + myrg_rprev.c myrg_rrnd.c myrg_rsame.c myrg_static.c myrg_update.c + myrg_write.c) diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am index 14e3295c1ae..19543927fd2 100644 --- a/myisammrg/Makefile.am +++ b/myisammrg/Makefile.am @@ -23,6 +23,6 @@ libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \ myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c \ myrg_rnext_same.c - +EXTRA_DIST = CMakeLists.txt # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 39fc425bf06..9f54b4fe192 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -34,7 +34,7 @@ benchdir_root= $(prefix) testdir = $(benchdir_root)/mysql-test EXTRA_SCRIPTS = mysql-test-run.sh install_test_db.sh valgrind.supp $(PRESCRIPTS) EXTRA_DIST = $(EXTRA_SCRIPTS) -GENSCRIPTS = mysql-test-run install_test_db +GENSCRIPTS = mysql-test-run install_test_db mtr PRESCRIPTS = mysql-test-run.pl test_SCRIPTS = $(GENSCRIPTS) $(PRESCRIPTS) test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem \ @@ -89,6 +89,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.*001 $(DESTDIR)$(testdir)/std_data + $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data @@ -111,6 +112,11 @@ std_data/server-cert.pem: $(top_srcdir)/SSL/$(@F) std_data/server-key.pem: $(top_srcdir)/SSL/$(@F) @RM@ -f $@; @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data +# mtr - a shortcut for executing mysql-test-run.pl +mtr: + $(RM) -f mtr + $(LN_S) mysql-test-run.pl mtr + SUFFIXES = .sh .sh: diff --git a/mysql-test/include/im_check_env.inc b/mysql-test/include/im_check_env.inc new file mode 100644 index 00000000000..019e0984614 --- /dev/null +++ b/mysql-test/include/im_check_env.inc @@ -0,0 +1,25 @@ +# This file is intended to be used in each IM-test. It contains stamements, +# that ensure that starting conditions (environment) for the IM-test are as +# expected. + +# Check the running instances. + +--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK) + +--connection mysql1_con + +SHOW VARIABLES LIKE 'server_id'; + +--source include/not_windows.inc + +--connection default + +# Let IM detect that mysqld1 is online. This delay should be longer than +# monitoring interval. + +--sleep 2 + +# Check that IM understands that mysqld1 is online, while mysqld2 is +# offline. + +SHOW INSTANCES; diff --git a/mysql-test/include/im_check_os.inc b/mysql-test/include/im_check_os.inc deleted file mode 100644 index 9465115feb5..00000000000 --- a/mysql-test/include/im_check_os.inc +++ /dev/null @@ -1,7 +0,0 @@ ---connect (dflt_server_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK) ---connection dflt_server_con - ---source include/not_windows.inc - ---connection default ---disconnect dflt_server_con diff --git a/mysql-test/include/loaddata_autocom.inc b/mysql-test/include/loaddata_autocom.inc new file mode 100644 index 00000000000..e5071c73c49 --- /dev/null +++ b/mysql-test/include/loaddata_autocom.inc @@ -0,0 +1,21 @@ +# Test if the engine does autocommit in LOAD DATA INFILE, or not +# (NDB wants to do, others don't). + +eval SET SESSION STORAGE_ENGINE = $engine_type; + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (a text, b text); +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +commit; +select count(*) from t1; +truncate table t1; +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +rollback; +select count(*) from t1; + +drop table t1; diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl index b3da6d97664..bdf91212b59 100644 --- a/mysql-test/lib/mtr_io.pl +++ b/mysql-test/lib/mtr_io.pl @@ -19,13 +19,39 @@ sub mtr_tonewfile($@); ############################################################################## sub mtr_get_pid_from_file ($) { - my $file= shift; + my $pid_file_path= shift; + my $TOTAL_ATTEMPTS= 30; + my $timeout= 1; - open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!"); - my $pid= <FILE>; - chomp($pid); - close FILE; - return $pid; + # We should read from the file until we get correct pid. As it is + # stated in BUG#21884, pid file can be empty at some moment. So, we should + # read it until we get valid data. + + for (my $cur_attempt= 1; $cur_attempt <= $TOTAL_ATTEMPTS; ++$cur_attempt) + { + mtr_debug("Reading pid file '$pid_file_path' " . + "($cur_attempt of $TOTAL_ATTEMPTS)..."); + + open(FILE, '<', $pid_file_path) + or mtr_error("can't open file \"$pid_file_path\": $!"); + + my $pid= <FILE>; + + chomp($pid) if defined $pid; + + close FILE; + + return $pid if defined $pid && $pid ne ''; + + mtr_debug("Pid file '$pid_file_path' is empty. " . + "Sleeping $timeout second(s)..."); + + sleep(1); + } + + mtr_error("Pid file '$pid_file_path' is corrupted. " . + "Can not retrieve PID in " . + ($timeout * $TOTAL_ATTEMPTS) . " seconds."); } sub mtr_get_opts_from_file ($) { diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index b5a2e5a4a68..0ab09a40b37 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -83,7 +83,14 @@ sub mtr_path_exists (@) { sub mtr_script_exists (@) { foreach my $path ( @_ ) { - return $path if -x $path; + if($::glob_win32) + { + return $path if -f $path; + } + else + { + return $path if -x $path; + } } if ( @_ == 1 ) { @@ -108,7 +115,14 @@ sub mtr_exe_exists (@) { map {$_.= ".exe"} @path if $::glob_win32; foreach my $path ( @path ) { - return $path if -x $path; + if($::glob_win32) + { + return $path if -f $path; + } + else + { + return $path if -x $path; + } } if ( @path == 1 ) { diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 0ca16b61fc2..bf869ca91c4 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -20,7 +20,29 @@ sub mtr_record_dead_children (); sub mtr_exit ($); sub sleep_until_file_created ($$$); sub mtr_kill_processes ($); -sub mtr_kill_process ($$$$); +sub mtr_ping_mysqld_server ($); + +# Private IM-related operations. + +sub mtr_im_kill_process ($$$$); +sub mtr_im_load_pids ($); +sub mtr_im_terminate ($); +sub mtr_im_check_alive ($); +sub mtr_im_check_main_alive ($); +sub mtr_im_check_angel_alive ($); +sub mtr_im_check_mysqlds_alive ($); +sub mtr_im_check_mysqld_alive ($$); +sub mtr_im_cleanup ($); +sub mtr_im_rm_file ($); +sub mtr_im_errlog ($); +sub mtr_im_kill ($); +sub mtr_im_wait_for_connection ($$$); +sub mtr_im_wait_for_mysqld($$$); + +# Public IM-related operations. + +sub mtr_im_start ($$); +sub mtr_im_stop ($); # static in C sub spawn_impl ($$$$$$$$); @@ -359,40 +381,54 @@ sub mtr_process_exit_status { sub mtr_kill_leftovers () { - # First, kill all masters and slaves that would conflict with - # this run. Make sure to remove the PID file, if any. - # FIXME kill IM manager first, else it will restart the servers, how?! + mtr_debug("mtr_kill_leftovers(): started."); + + mtr_im_stop($::instance_manager); + + # Kill mysqld servers (masters and slaves) that would conflict with this + # run. Make sure to remove the PID file, if any. + # Don't touch IM-managed mysqld instances -- they should be stopped by + # mtr_im_stop(). + + mtr_debug("Collecting mysqld-instances to shutdown..."); my @args; - for ( my $idx; $idx < 2; $idx++ ) + for ( my $idx= 0; $idx < 2; $idx++ ) { - push(@args,{ - pid => 0, # We don't know the PID - pidfile => $::instance_manager->{'instances'}->[$idx]->{'path_pid'}, - sockfile => $::instance_manager->{'instances'}->[$idx]->{'path_sock'}, - port => $::instance_manager->{'instances'}->[$idx]->{'port'}, - }); - } + my $pidfile= $::master->[$idx]->{'path_mypid'}; + my $sockfile= $::master->[$idx]->{'path_mysock'}; + my $port= $::master->[$idx]->{'path_myport'}; - for ( my $idx; $idx < 2; $idx++ ) - { push(@args,{ pid => 0, # We don't know the PID - pidfile => $::master->[$idx]->{'path_mypid'}, - sockfile => $::master->[$idx]->{'path_mysock'}, - port => $::master->[$idx]->{'path_myport'}, + pidfile => $pidfile, + sockfile => $sockfile, + port => $port, }); + + mtr_debug(" - Master mysqld " . + "(idx: $idx; pid: '$pidfile'; socket: '$sockfile'; port: $port)"); + $::master->[$idx]->{'pid'}= 0; # Assume we are done with it } - for ( my $idx; $idx < 3; $idx++ ) + for ( my $idx= 0; $idx < 3; $idx++ ) { + my $pidfile= $::slave->[$idx]->{'path_mypid'}; + my $sockfile= $::slave->[$idx]->{'path_mysock'}; + my $port= $::slave->[$idx]->{'path_myport'}; + push(@args,{ pid => 0, # We don't know the PID - pidfile => $::slave->[$idx]->{'path_mypid'}, - sockfile => $::slave->[$idx]->{'path_mysock'}, - port => $::slave->[$idx]->{'path_myport'}, + pidfile => $pidfile, + sockfile => $sockfile, + port => $port, }); + + mtr_debug(" - Slave mysqld " . + "(idx: $idx; pid: '$pidfile'; socket: '$sockfile'; port: $port)"); + + $::slave->[$idx]->{'pid'}= 0; # Assume we are done with it } mtr_mysqladmin_shutdown(\@args, 20); @@ -413,6 +449,8 @@ sub mtr_kill_leftovers () { # FIXME $path_run_dir or something my $rundir= "$::opt_vardir/run"; + mtr_debug("Processing PID files in directory '$rundir'..."); + if ( -d $rundir ) { opendir(RUNDIR, $rundir) @@ -426,8 +464,12 @@ sub mtr_kill_leftovers () { if ( -f $pidfile ) { + mtr_debug("Processing PID file: '$pidfile'..."); + my $pid= mtr_get_pid_from_file($pidfile); + mtr_debug("Got pid: $pid from file '$pidfile'"); + # Race, could have been removed between I tested with -f # and the unlink() below, so I better check again with -f @@ -438,14 +480,24 @@ sub mtr_kill_leftovers () { if ( $::glob_cygwin_perl or kill(0, $pid) ) { + mtr_debug("There is process with pid $pid -- scheduling for kill."); push(@pids, $pid); # We know (cygwin guess) it exists } + else + { + mtr_debug("There is no process with pid $pid -- skipping."); + } } } closedir(RUNDIR); if ( @pids ) { + mtr_debug("Killing the following processes with PID files: " . + join(' ', @pids) . "..."); + + start_reap_all(); + if ( $::glob_cygwin_perl ) { # We have no (easy) way of knowing the Cygwin controlling @@ -459,6 +511,7 @@ sub mtr_kill_leftovers () { my $retries= 10; # 10 seconds do { + mtr_debug("Sending SIGKILL to pids: " . join(' ', @pids)); kill(9, @pids); mtr_debug("Sleep 1 second waiting for processes to die"); sleep(1) # Wait one second @@ -469,19 +522,29 @@ sub mtr_kill_leftovers () { mtr_warning("can't kill process(es) " . join(" ", @pids)); } } + + stop_reap_all(); } } + else + { + mtr_debug("Directory for PID files ($rundir) does not exist."); + } # We may have failed everything, bug we now check again if we have # the listen ports free to use, and if they are free, just go for it. + mtr_debug("Checking known mysqld servers..."); + foreach my $srv ( @args ) { - if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) + if ( mtr_ping_mysqld_server($srv->{'port'}) ) { mtr_warning("can't kill old mysqld holding port $srv->{'port'}"); } } + + mtr_debug("mtr_kill_leftovers(): finished."); } ############################################################################## @@ -653,10 +716,15 @@ sub mtr_mysqladmin_shutdown { my %mysql_admin_pids; my @to_kill_specs; + mtr_debug("mtr_mysqladmin_shutdown(): starting..."); + mtr_debug("Collecting mysqld-instances to shutdown..."); + foreach my $srv ( @$spec ) { - if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) + if ( mtr_ping_mysqld_server($srv->{'port'}) ) { + mtr_debug("Mysqld (port: $srv->{port}) needs to be stopped."); + push(@to_kill_specs, $srv); } } @@ -688,6 +756,9 @@ sub mtr_mysqladmin_shutdown { mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo"); mtr_add_arg($args, "shutdown"); + mtr_debug("Shutting down mysqld " . + "(port: $srv->{port}; socket: '$srv->{sockfile}')..."); + my $path_mysqladmin_log= "$::opt_vardir/log/mysqladmin.log"; my $pid= mtr_spawn($::exe_mysqladmin, $args, "", $path_mysqladmin_log, $path_mysqladmin_log, "", @@ -719,14 +790,18 @@ sub mtr_mysqladmin_shutdown { my $res= 1; # If we just fall through, we are done # in the sense that the servers don't # listen to their ports any longer + + mtr_debug("Waiting for mysqld servers to stop..."); + TIME: while ( $timeout-- ) { foreach my $srv ( @to_kill_specs ) { $res= 1; # We are optimistic - if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) + if ( mtr_ping_mysqld_server($srv->{'port'}) ) { + mtr_debug("Mysqld (port: $srv->{port}) is still alive."); mtr_debug("Sleep 1 second waiting for processes to stop using port"); sleep(1); # One second $res= 0; @@ -736,7 +811,14 @@ sub mtr_mysqladmin_shutdown { last; # If we got here, we are done } - $timeout or mtr_debug("At least one server is still listening to its port"); + if ($res) + { + mtr_debug("mtr_mysqladmin_shutdown(): All mysqld instances are down."); + } + else + { + mtr_debug("mtr_mysqladmin_shutdown(): At least one server is alive."); + } return $res; } @@ -795,7 +877,7 @@ sub stop_reap_all { $SIG{CHLD}= 'DEFAULT'; } -sub mtr_ping_mysqld_server () { +sub mtr_ping_mysqld_server ($) { my $port= shift; my $remote= "localhost"; @@ -810,13 +892,18 @@ sub mtr_ping_mysqld_server () { { mtr_error("can't create socket: $!"); } + + mtr_debug("Pinging server (port: $port)..."); + if ( connect(SOCK, $paddr) ) { + mtr_debug("Server (port: $port) is alive."); close(SOCK); # FIXME check error? return 1; } else { + mtr_debug("Server (port: $port) is dead."); return 0; } } @@ -886,34 +973,6 @@ sub mtr_kill_processes ($) { } } - -sub mtr_kill_process ($$$$) { - my $pid= shift; - my $signal= shift; - my $total_retries= shift; - my $timeout= shift; - - for (my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt) - { - mtr_debug("Sending $signal to $pid..."); - - kill($signal, $pid); - - unless (kill (0, $pid)) - { - mtr_debug("Process $pid died."); - return; - } - - mtr_debug("Sleeping $timeout second(s) waiting for processes to die..."); - - sleep($timeout); - } - - mtr_debug("Process $pid is still alive after $total_retries " . - "of sending signal $signal."); -} - ############################################################################## # # When we exit, we kill off all children @@ -943,4 +1002,676 @@ sub mtr_exit ($) { exit($code); } +############################################################################## +# +# Instance Manager management routines. +# +############################################################################## + +sub mtr_im_kill_process ($$$$) { + my $pid_lst= shift; + my $signal= shift; + my $total_retries= shift; + my $timeout= shift; + + my %pids; + + foreach my $pid (@{$pid_lst}) + { + $pids{$pid}= 1; + } + + for (my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt) + { + foreach my $pid (keys %pids) + { + mtr_debug("Sending $signal to $pid..."); + + kill($signal, $pid); + + unless (kill (0, $pid)) + { + mtr_debug("Process $pid died."); + delete $pids{$pid}; + } + } + + return if scalar keys %pids == 0; + + mtr_debug("Sleeping $timeout second(s) waiting for processes to die..."); + + sleep($timeout); + } + + mtr_debug("Process(es) " . + join(' ', keys %pids) . + " is still alive after $total_retries " . + "of sending signal $signal."); +} + +########################################################################### + +sub mtr_im_load_pids($) { + my $instance_manager= shift; + + mtr_debug("Loading PID files..."); + + # Obtain mysqld-process pids. + + my $instances = $instance_manager->{'instances'}; + + for (my $idx= 0; $idx < 2; ++$idx) + { + mtr_debug("IM-guarded mysqld[$idx] PID file: '" . + $instances->[$idx]->{'path_pid'} . "'."); + + my $mysqld_pid; + + if (-r $instances->[$idx]->{'path_pid'}) + { + $mysqld_pid= mtr_get_pid_from_file($instances->[$idx]->{'path_pid'}); + mtr_debug("IM-guarded mysqld[$idx] PID: $mysqld_pid."); + } + else + { + $mysqld_pid= undef; + mtr_debug("IM-guarded mysqld[$idx]: no PID file."); + } + + $instances->[$idx]->{'pid'}= $mysqld_pid; + } + + # Re-read Instance Manager PIDs from the file, since during tests Instance + # Manager could have been restarted, so its PIDs could have been changed. + + # - IM-main + + mtr_debug("IM-main PID file: '$instance_manager->{path_pid}'."); + + if (-f $instance_manager->{'path_pid'}) + { + $instance_manager->{'pid'} = + mtr_get_pid_from_file($instance_manager->{'path_pid'}); + + mtr_debug("IM-main PID: $instance_manager->{pid}."); + } + else + { + mtr_debug("IM-main: no PID file."); + $instance_manager->{'pid'}= undef; + } + + # - IM-angel + + mtr_debug("IM-angel PID file: '$instance_manager->{path_angel_pid}'."); + + if (-f $instance_manager->{'path_angel_pid'}) + { + $instance_manager->{'angel_pid'} = + mtr_get_pid_from_file($instance_manager->{'path_angel_pid'}); + + mtr_debug("IM-angel PID: $instance_manager->{'angel_pid'}."); + } + else + { + mtr_debug("IM-angel: no PID file."); + $instance_manager->{'angel_pid'} = undef; + } +} + +########################################################################### + +sub mtr_im_terminate($) { + my $instance_manager= shift; + + # Load pids from pid-files. We should do it first of all, because IM deletes + # them on shutdown. + + mtr_im_load_pids($instance_manager); + + mtr_debug("Shutting Instance Manager down..."); + + # Ignoring SIGCHLD so that all children could rest in peace. + + start_reap_all(); + + # Send SIGTERM to IM-main. + + if (defined $instance_manager->{'pid'}) + { + mtr_debug("IM-main pid: $instance_manager->{pid}."); + mtr_debug("Stopping IM-main..."); + + mtr_im_kill_process([ $instance_manager->{'pid'} ], 'TERM', 10, 1); + } + else + { + mtr_debug("IM-main pid: n/a."); + } + + # If IM-angel was alive, wait for it to die. + + if (defined $instance_manager->{'angel_pid'}) + { + mtr_debug("IM-angel pid: $instance_manager->{'angel_pid'}."); + mtr_debug("Waiting for IM-angel to die..."); + + my $total_attempts= 10; + + for (my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt) + { + unless (kill (0, $instance_manager->{'angel_pid'})) + { + mtr_debug("IM-angel died."); + last; + } + + sleep(1); + } + } + else + { + mtr_debug("IM-angel pid: n/a."); + } + + stop_reap_all(); + + # Re-load PIDs. + + mtr_im_load_pids($instance_manager); +} + +########################################################################### + +sub mtr_im_check_alive($) { + my $instance_manager= shift; + + mtr_debug("Checking whether IM-components are alive..."); + + return 1 if mtr_im_check_main_alive($instance_manager); + + return 1 if mtr_im_check_angel_alive($instance_manager); + + return 1 if mtr_im_check_mysqlds_alive($instance_manager); + + return 0; +} + +########################################################################### + +sub mtr_im_check_main_alive($) { + my $instance_manager= shift; + + # Check that the process, that we know to be IM's, is dead. + + if (defined $instance_manager->{'pid'}) + { + if (kill (0, $instance_manager->{'pid'})) + { + mtr_debug("IM-main (PID: $instance_manager->{pid}) is alive."); + return 1; + } + else + { + mtr_debug("IM-main (PID: $instance_manager->{pid}) is dead."); + } + } + else + { + mtr_debug("No PID file for IM-main."); + } + + # Check that IM does not accept client connections. + + if (mtr_ping_mysqld_server($instance_manager->{'port'})) + { + mtr_debug("IM-main (port: $instance_manager->{port}) " . + "is accepting connections."); + + mtr_im_errlog("IM-main is accepting connections on port " . + "$instance_manager->{port}, but there is no " . + "process information."); + return 1; + } + else + { + mtr_debug("IM-main (port: $instance_manager->{port}) " . + "does not accept connections."); + return 0; + } +} + +########################################################################### + +sub mtr_im_check_angel_alive($) { + my $instance_manager= shift; + + # Check that the process, that we know to be the Angel, is dead. + + if (defined $instance_manager->{'angel_pid'}) + { + if (kill (0, $instance_manager->{'angel_pid'})) + { + mtr_debug("IM-angel (PID: $instance_manager->{angel_pid}) is alive."); + return 1; + } + else + { + mtr_debug("IM-angel (PID: $instance_manager->{angel_pid}) is dead."); + return 0; + } + } + else + { + mtr_debug("No PID file for IM-angel."); + return 0; + } +} + +########################################################################### + +sub mtr_im_check_mysqlds_alive($) { + my $instance_manager= shift; + + mtr_debug("Checking for IM-guarded mysqld instances..."); + + my $instances = $instance_manager->{'instances'}; + + for (my $idx= 0; $idx < 2; ++$idx) + { + mtr_debug("Checking mysqld[$idx]..."); + + return 1 + if mtr_im_check_mysqld_alive($instance_manager, $instances->[$idx]); + } +} + +########################################################################### + +sub mtr_im_check_mysqld_alive($$) { + my $instance_manager= shift; + my $mysqld_instance= shift; + + # Check that the process is dead. + + if (defined $instance_manager->{'pid'}) + { + if (kill (0, $instance_manager->{'pid'})) + { + mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is alive."); + return 1; + } + else + { + mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is dead."); + } + } + else + { + mtr_debug("No PID file for mysqld instance."); + } + + # Check that mysqld does not accept client connections. + + if (mtr_ping_mysqld_server($mysqld_instance->{'port'})) + { + mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " . + "is accepting connections."); + + mtr_im_errlog("Mysqld is accepting connections on port " . + "$mysqld_instance->{port}, but there is no " . + "process information."); + return 1; + } + else + { + mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " . + "does not accept connections."); + return 0; + } +} + +########################################################################### + +sub mtr_im_cleanup($) { + my $instance_manager= shift; + + mtr_im_rm_file($instance_manager->{'path_pid'}); + mtr_im_rm_file($instance_manager->{'path_sock'}); + + mtr_im_rm_file($instance_manager->{'path_angel_pid'}); + + for (my $idx= 0; $idx < 2; ++$idx) + { + mtr_im_rm_file($instance_manager->{'instances'}->[$idx]->{'path_pid'}); + mtr_im_rm_file($instance_manager->{'instances'}->[$idx]->{'path_sock'}); + } +} + +########################################################################### + +sub mtr_im_rm_file($) +{ + my $file_path= shift; + + if (-f $file_path) + { + mtr_debug("Removing '$file_path'..."); + + mtr_warning("Can not remove '$file_path'.") + unless unlink($file_path); + } + else + { + mtr_debug("File '$file_path' does not exist already."); + } +} + +########################################################################### + +sub mtr_im_errlog($) { + my $msg= shift; + + # Complain in error log so that a warning will be shown. + # + # TODO: unless BUG#20761 is fixed, we will print the warning to stdout, so + # that it can be seen on console and does not produce pushbuild error. + + # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err"; + # + # open (ERRLOG, ">>$errlog") || + # mtr_error("Can not open error log ($errlog)"); + # + # my $ts= localtime(); + # print ERRLOG + # "Warning: [$ts] $msg\n"; + # + # close ERRLOG; + + my $ts= localtime(); + print "Warning: [$ts] $msg\n"; +} + +########################################################################### + +sub mtr_im_kill($) { + my $instance_manager= shift; + + # Re-load PIDs. That can be useful because some processes could have been + # restarted. + + mtr_im_load_pids($instance_manager); + + # Ignoring SIGCHLD so that all children could rest in peace. + + start_reap_all(); + + # Kill IM-angel first of all. + + if (defined $instance_manager->{'angel_pid'}) + { + mtr_debug("Killing IM-angel (PID: $instance_manager->{angel_pid})..."); + mtr_im_kill_process([ $instance_manager->{'angel_pid'} ], 'KILL', 10, 1) + } + else + { + mtr_debug("IM-angel is dead."); + } + + # Re-load PIDs again. + + mtr_im_load_pids($instance_manager); + + # Kill IM-main. + + if (defined $instance_manager->{'pid'}) + { + mtr_debug("Killing IM-main (PID: $instance_manager->pid})..."); + mtr_im_kill_process([ $instance_manager->{'pid'} ], 'KILL', 10, 1); + } + else + { + mtr_debug("IM-main is dead."); + } + + # Re-load PIDs again. + + mtr_im_load_pids($instance_manager); + + # Kill guarded mysqld instances. + + my @mysqld_pids; + + mtr_debug("Collecting PIDs of mysqld instances to kill..."); + + for (my $idx= 0; $idx < 2; ++$idx) + { + my $pid= $instance_manager->{'instances'}->[$idx]->{'pid'}; + + next unless defined $pid; + + mtr_debug(" - IM-guarded mysqld[$idx] PID: $pid."); + + push (@mysqld_pids, $pid); + } + + if (scalar @mysqld_pids > 0) + { + mtr_debug("Killing IM-guarded mysqld instances..."); + mtr_im_kill_process(\@mysqld_pids, 'KILL', 10, 1); + } + + # That's all. + + stop_reap_all(); +} + +############################################################################## + +sub mtr_im_wait_for_connection($$$) { + my $instance_manager= shift; + my $total_attempts= shift; + my $connect_timeout= shift; + + mtr_debug("Waiting for IM on port $instance_manager->{port} " . + "to start accepting connections..."); + + for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt) + { + mtr_debug("Trying to connect to IM ($cur_attempt of $total_attempts)..."); + + if (mtr_ping_mysqld_server($instance_manager->{'port'})) + { + mtr_debug("IM is accepting connections " . + "on port $instance_manager->{port}."); + return 1; + } + + mtr_debug("Sleeping $connect_timeout..."); + sleep($connect_timeout); + } + + mtr_debug("IM does not accept connections " . + "on port $instance_manager->{port} after " . + ($total_attempts * $connect_timeout) . " seconds."); + + return 0; +} + +############################################################################## + +sub mtr_im_wait_for_mysqld($$$) { + my $mysqld= shift; + my $total_attempts= shift; + my $connect_timeout= shift; + + mtr_debug("Waiting for IM-guarded mysqld on port $mysqld->{port} " . + "to start accepting connections..."); + + for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt) + { + mtr_debug("Trying to connect to mysqld " . + "($cur_attempt of $total_attempts)..."); + + if (mtr_ping_mysqld_server($mysqld->{'port'})) + { + mtr_debug("Mysqld is accepting connections " . + "on port $mysqld->{port}."); + return 1; + } + + mtr_debug("Sleeping $connect_timeout..."); + sleep($connect_timeout); + } + + mtr_debug("Mysqld does not accept connections " . + "on port $mysqld->{port} after " . + ($total_attempts * $connect_timeout) . " seconds."); + + return 0; +} + +############################################################################## + +sub mtr_im_start($$) { + my $instance_manager = shift; + my $opts = shift; + + mtr_debug("Starting Instance Manager..."); + + my $args; + mtr_init_args(\$args); + mtr_add_arg($args, "--defaults-file=%s", + $instance_manager->{'defaults_file'}); + + foreach my $opt (@{$opts}) + { + mtr_add_arg($args, $opt); + } + + $instance_manager->{'pid'} = + mtr_spawn( + $::exe_im, # path to the executable + $args, # cmd-line args + '', # stdin + $instance_manager->{'path_log'}, # stdout + $instance_manager->{'path_err'}, # stderr + '', # pid file path (not used) + { append_log_file => 1 } # append log files + ); + + if ( ! $instance_manager->{'pid'} ) + { + mtr_report('Could not start Instance Manager'); + return; + } + + # Instance Manager can be run in daemon mode. In this case, it creates + # several processes and the parent process, created by mtr_spawn(), exits just + # after start. So, we have to obtain Instance Manager PID from the PID file. + + if ( ! sleep_until_file_created( + $instance_manager->{'path_pid'}, + $instance_manager->{'start_timeout'}, + -1)) # real PID is still unknown + { + mtr_report("Instance Manager PID file is missing"); + return; + } + + $instance_manager->{'pid'} = + mtr_get_pid_from_file($instance_manager->{'path_pid'}); + + mtr_debug("Instance Manager started. PID: $instance_manager->{pid}."); + + # Wait until we can connect to IM. + + my $IM_CONNECT_TIMEOUT= 30; + + unless (mtr_im_wait_for_connection($instance_manager, + $IM_CONNECT_TIMEOUT, 1)) + { + mtr_debug("Can not connect to Instance Manager " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + mtr_debug("Aborting test suite..."); + + mtr_kill_leftovers(); + + mtr_error("Can not connect to Instance Manager " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + } + + # Wait until we can connect to guarded mysqld-instances + # (in other words -- wait for IM to start guarded instances). + + for (my $idx= 0; $idx < 2; ++$idx) + { + my $mysqld= $instance_manager->{'instances'}->[$idx]; + + next if exists $mysqld->{'nonguarded'}; + + mtr_debug("Waiting for mysqld[$idx] to start..."); + + unless (mtr_im_wait_for_mysqld($mysqld, 30, 1)) + { + mtr_debug("Can not connect to mysqld[$idx] " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + mtr_debug("Aborting test suite..."); + + mtr_kill_leftovers(); + + mtr_error("Can not connect to mysqld[$idx] " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + } + + mtr_debug("mysqld[$idx] started."); + } + + mtr_debug("Instance Manager started."); +} + +############################################################################## + +sub mtr_im_stop($) { + my $instance_manager= shift; + + mtr_debug("Stopping Instance Manager..."); + + # Try graceful shutdown. + + mtr_im_terminate($instance_manager); + + # Check that all processes died. + + unless (mtr_im_check_alive($instance_manager)) + { + mtr_debug("Instance Manager has been stopped successfully."); + mtr_im_cleanup($instance_manager); + return 1; + } + + # Instance Manager don't want to die. We should kill it. + + mtr_im_errlog("Instance Manager did not shutdown gracefully."); + + mtr_im_kill($instance_manager); + + # Check again that all IM-related processes have been killed. + + my $im_is_alive= mtr_im_check_alive($instance_manager); + + mtr_im_cleanup($instance_manager); + + if ($im_is_alive) + { + mtr_error("Can not kill Instance Manager or its children."); + return 0; + } + + mtr_debug("Instance Manager has been killed successfully."); + return 1; +} + +########################################################################### + 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 91a9a758d1d..f0eb7f3bda4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -133,7 +133,6 @@ our @mysqld_src_dirs= our $glob_win32= 0; # OS and native Win32 executables our $glob_win32_perl= 0; # ActiveState Win32 Perl our $glob_cygwin_perl= 0; # Cygwin Perl -our $glob_cygwin_shell= undef; our $glob_mysql_test_dir= undef; our $glob_mysql_bench_dir= undef; our $glob_hostname= undef; @@ -187,6 +186,7 @@ our $exe_mysqltest; our $exe_slave_mysqld; our $exe_im; our $exe_my_print_defaults; +our $exe_perror; our $lib_udf_example; our $exe_libtool; @@ -335,7 +335,7 @@ sub snapshot_setup (); sub executable_setup (); sub environment_setup (); sub kill_running_server (); -sub kill_and_cleanup (); +sub cleanup_stale_files (); sub check_ssl_support (); sub check_running_as_root(); sub check_ndbcluster_support (); @@ -355,8 +355,6 @@ sub mysqld_arguments ($$$$$$); sub stop_masters_slaves (); sub stop_masters (); sub stop_slaves (); -sub im_start ($$); -sub im_stop ($); sub run_mysqltest ($); sub usage ($); @@ -465,10 +463,7 @@ sub initial_setup () { { # Windows programs like 'mysqld' needs Windows paths $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`; - my $shell= $ENV{'SHELL'} || "/bin/bash"; - $glob_cygwin_shell= `cygpath -w "$shell"`; # The Windows path c:\... chomp($glob_mysql_test_dir); - chomp($glob_cygwin_shell); } $glob_basedir= dirname($glob_mysql_test_dir); $glob_mysql_bench_dir= "$glob_basedir/mysql-bench"; # FIXME make configurable @@ -498,7 +493,7 @@ sub command_line_setup () { my $opt_master_myport= 9306; my $opt_slave_myport= 9308; $opt_ndbcluster_port= 9350; - my $im_port= 9310; + my $im_port= 9311; my $im_mysqld1_port= 9312; my $im_mysqld2_port= 9314; @@ -811,6 +806,13 @@ sub command_line_setup () { $opt_with_ndbcluster= 0; } + # Check IM arguments + if ( $glob_win32 ) + { + mtr_report("Disable Instance manager - not supported on Windows"); + $opt_skip_im= 1; + } + # Check valgrind arguments if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options) { @@ -1036,18 +1038,30 @@ sub executable_setup () { if ( $glob_win32 ) { $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", - "$glob_basedir/client_debug", + "$glob_basedir/client_debug", + "$glob_basedir/client/release", + "$glob_basedir/client/debug", "$glob_basedir/bin",); $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-max-nt", "$path_client_bindir/mysqld-max", "$path_client_bindir/mysqld-nt", "$path_client_bindir/mysqld", "$path_client_bindir/mysqld-debug", - "$path_client_bindir/mysqld-max"); - $path_language= mtr_path_exists("$glob_basedir/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets"); + "$path_client_bindir/mysqld-max", + "$glob_basedir/sql/release/mysqld", + "$glob_basedir/sql/debug/mysqld"); + $path_language= mtr_path_exists("$glob_basedir/share/english/", + "$glob_basedir/sql/share/english/"); + $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets", + "$glob_basedir/sql/share/charsets/"); $exe_my_print_defaults= - mtr_exe_exists("$path_client_bindir/my_print_defaults"); + mtr_exe_exists("$path_client_bindir/my_print_defaults", + "$glob_basedir/extra/release/my_print_defaults", + "$glob_basedir/extra/debug/my_print_defaults"); + $exe_perror= + mtr_exe_exists("$path_client_bindir/perror", + "$glob_basedir/extra/release/perror", + "$glob_basedir/extra/debug/perror"); } else { @@ -1060,6 +1074,8 @@ sub executable_setup () { "$glob_basedir/server-tools/instance-manager/mysqlmanager"); $exe_my_print_defaults= mtr_exe_exists("$glob_basedir/extra/my_print_defaults"); + $exe_perror= + mtr_exe_exists("$glob_basedir/extra/perror"); } if ( $glob_use_embedded_server ) @@ -1076,6 +1092,9 @@ sub executable_setup () { $exe_mysql_client_test= mtr_exe_exists("$glob_basedir/tests/mysql_client_test", "$path_client_bindir/mysql_client_test", + "$glob_basedir/tests/release/mysql_client_test", + "$glob_basedir/tests/debug/mysql_client_test", + "$path_client_bindir/mysql_client_test", "/usr/bin/false"); } $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); @@ -1086,7 +1105,8 @@ sub executable_setup () { $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); $exe_mysql_fix_system_tables= - mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables"); + mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", + "/usr/bin/false"); $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools"); $exe_ndb_mgm= "$glob_basedir/ndb/src/mgmclient/ndb_mgm"; $lib_udf_example= @@ -1104,9 +1124,12 @@ sub executable_setup () { $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); $exe_mysql_fix_system_tables= mtr_script_exists("$path_client_bindir/mysql_fix_privilege_tables", - "$glob_basedir/scripts/mysql_fix_privilege_tables"); + "$glob_basedir/scripts/mysql_fix_privilege_tables", + "/usr/bin/false"); $exe_my_print_defaults= mtr_exe_exists("$path_client_bindir/my_print_defaults"); + $exe_perror= + mtr_exe_exists("$path_client_bindir/perror"); $path_language= mtr_path_exists("$glob_basedir/share/mysql/english/", "$glob_basedir/share/english/"); @@ -1136,7 +1159,9 @@ sub executable_setup () { } else { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); + $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest", + "$glob_basedir/client/release/mysqltest", + "$glob_basedir/client/debug/mysqltest"); $exe_mysql_client_test= mtr_exe_exists("$path_client_bindir/mysql_client_test", "/usr/bin/false"); # FIXME temporary @@ -1164,28 +1189,33 @@ sub executable_setup () { sub environment_setup () { + my $extra_ld_library_paths; + # -------------------------------------------------------------------------- - # We might not use a standard installation directory, like /usr/lib. - # Set LD_LIBRARY_PATH to make sure we find our installed libraries. + # Setup LD_LIBRARY_PATH so the libraries from this distro/clone + # are used in favor of the system installed ones # -------------------------------------------------------------------------- - - unless ( $opt_source_dist ) + if ( $opt_source_dist ) + { + $extra_ld_library_paths= "$glob_basedir/libmysql/.libs/"; + } + else { - $ENV{'LD_LIBRARY_PATH'}= - "$glob_basedir/lib" . - ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); - $ENV{'DYLD_LIBRARY_PATH'}= - "$glob_basedir/lib" . - ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : ""); + $extra_ld_library_paths= "$glob_basedir/lib"; } # -------------------------------------------------------------------------- # Add the path where mysqld will find udf_example.so # -------------------------------------------------------------------------- + $extra_ld_library_paths .= ":" . + ($lib_udf_example ? dirname($lib_udf_example) : ""); + $ENV{'LD_LIBRARY_PATH'}= - ($lib_udf_example ? dirname($lib_udf_example) : "") . + "$extra_ld_library_paths" . ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); - + $ENV{'DYLD_LIBRARY_PATH'}= + "$extra_ld_library_paths" . + ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : ""); # -------------------------------------------------------------------------- # Also command lines in .opt files may contain env vars @@ -1284,6 +1314,7 @@ sub kill_running_server () { mtr_report("Killing Possible Leftover Processes"); mkpath("$opt_vardir/log"); # Needed for mysqladmin log + mtr_kill_leftovers(); $using_ndbcluster_master= $opt_with_ndbcluster; @@ -1292,9 +1323,7 @@ sub kill_running_server () { } } -sub kill_and_cleanup () { - - kill_running_server (); +sub cleanup_stale_files () { mtr_report("Removing Stale Files"); @@ -1673,13 +1702,11 @@ sub run_suite () { sub initialize_servers () { if ( ! $glob_use_running_server ) { - if ( $opt_start_dirty ) - { - kill_running_server(); - } - else + kill_running_server(); + + unless ( $opt_start_dirty ) { - kill_and_cleanup(); + cleanup_stale_files(); mysql_install_db(); if ( $opt_force ) { @@ -2081,7 +2108,7 @@ sub run_testcase ($) { im_create_defaults_file($instance_manager); - im_start($instance_manager, $tinfo->{im_opts}); + mtr_im_start($instance_manager, $tinfo->{im_opts}); } # ---------------------------------------------------------------------- @@ -2176,10 +2203,9 @@ sub run_testcase ($) { # Stop Instance Manager if we are processing an IM-test case. # ---------------------------------------------------------------------- - if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' and - $instance_manager->{'pid'} ) + if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' ) { - im_stop($instance_manager); + mtr_im_stop($instance_manager); } } @@ -2707,11 +2733,8 @@ sub stop_masters_slaves () { print "Ending Tests\n"; - if ( $instance_manager->{'pid'} ) - { - print "Shutting-down Instance Manager\n"; - im_stop($instance_manager); - } + print "Shutting-down Instance Manager\n"; + mtr_im_stop($instance_manager); print "Shutting-down MySQL daemon\n\n"; stop_masters(); @@ -2773,201 +2796,6 @@ sub stop_slaves () { mtr_stop_mysqld_servers(\@args); } -############################################################################## -# -# Instance Manager management routines. -# -############################################################################## - -sub im_start($$) { - my $instance_manager = shift; - my $opts = shift; - - my $args; - mtr_init_args(\$args); - mtr_add_arg($args, "--defaults-file=%s", - $instance_manager->{'defaults_file'}); - - foreach my $opt (@{$opts}) - { - mtr_add_arg($args, $opt); - } - - $instance_manager->{'pid'} = - mtr_spawn( - $exe_im, # path to the executable - $args, # cmd-line args - '', # stdin - $instance_manager->{'path_log'}, # stdout - $instance_manager->{'path_err'}, # stderr - '', # pid file path (not used) - { append_log_file => 1 } # append log files - ); - - if ( ! $instance_manager->{'pid'} ) - { - mtr_report('Could not start Instance Manager'); - return; - } - - # Instance Manager can be run in daemon mode. In this case, it creates - # several processes and the parent process, created by mtr_spawn(), exits just - # after start. So, we have to obtain Instance Manager PID from the PID file. - - if ( ! sleep_until_file_created( - $instance_manager->{'path_pid'}, - $instance_manager->{'start_timeout'}, - -1)) # real PID is still unknown - { - mtr_report("Instance Manager PID file is missing"); - return; - } - - $instance_manager->{'pid'} = - mtr_get_pid_from_file($instance_manager->{'path_pid'}); -} - - -sub im_stop($) { - my $instance_manager = shift; - - # Obtain mysqld-process pids before we start stopping IM (it can delete pid - # files). - - my @mysqld_pids = (); - my $instances = $instance_manager->{'instances'}; - - push(@mysqld_pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'})) - if -r $instances->[0]->{'path_pid'}; - - push(@mysqld_pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'})) - if -r $instances->[1]->{'path_pid'}; - - # Re-read pid from the file, since during tests Instance Manager could have - # been restarted, so its pid could have been changed. - - $instance_manager->{'pid'} = - mtr_get_pid_from_file($instance_manager->{'path_pid'}) - if -f $instance_manager->{'path_pid'}; - - if (-f $instance_manager->{'path_angel_pid'}) - { - $instance_manager->{'angel_pid'} = - mtr_get_pid_from_file($instance_manager->{'path_angel_pid'}) - } - else - { - $instance_manager->{'angel_pid'} = undef; - } - - # Inspired from mtr_stop_mysqld_servers(). - - start_reap_all(); - - # Try graceful shutdown. - - mtr_debug("IM-main pid: $instance_manager->{'pid'}"); - mtr_debug("Stopping IM-main..."); - - mtr_kill_process($instance_manager->{'pid'}, 'TERM', 10, 1); - - # If necessary, wait for angel process to die. - - if (defined $instance_manager->{'angel_pid'}) - { - mtr_debug("IM-angel pid: $instance_manager->{'angel_pid'}"); - mtr_debug("Waiting for IM-angel to die..."); - - my $total_attempts= 10; - - for (my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt) - { - unless (kill (0, $instance_manager->{'angel_pid'})) - { - mtr_debug("IM-angel died."); - last; - } - - sleep(1); - } - } - - # Check that all processes died. - - my $clean_shutdown= 0; - - while (1) - { - if (kill (0, $instance_manager->{'pid'})) - { - mtr_debug("IM-main is still alive."); - last; - } - - if (defined $instance_manager->{'angel_pid'} && - kill (0, $instance_manager->{'angel_pid'})) - { - mtr_debug("IM-angel is still alive."); - last; - } - - foreach my $pid (@mysqld_pids) - { - if (kill (0, $pid)) - { - mtr_debug("Guarded mysqld ($pid) is still alive."); - last; - } - } - - $clean_shutdown= 1; - last; - } - - # Kill leftovers (the order is important). - - unless ($clean_shutdown) - { - - if (defined $instance_manager->{'angel_pid'}) - { - mtr_debug("Killing IM-angel..."); - mtr_kill_process($instance_manager->{'angel_pid'}, 'KILL', 10, 1) - } - - mtr_debug("Killing IM-main..."); - mtr_kill_process($instance_manager->{'pid'}, 'KILL', 10, 1); - - # Shutdown managed mysqld-processes. Some of them may be nonguarded, so IM - # will not stop them on shutdown. So, we should firstly try to end them - # legally. - - mtr_debug("Killing guarded mysqld(s)..."); - mtr_kill_processes(\@mysqld_pids); - - # Complain in error log so that a warning will be shown. - - my $errlog= "$opt_vardir/log/mysql-test-run.pl.err"; - - open (ERRLOG, ">>$errlog") || - mtr_error("Can not open error log ($errlog)"); - - my $ts= localtime(); - print ERRLOG - "Warning: [$ts] Instance Manager did not shutdown gracefully.\n"; - - close ERRLOG; - } - - # That's all. - - stop_reap_all(); - - $instance_manager->{'pid'} = undef; - $instance_manager->{'angel_pid'} = undef; -} - - # # Run include/check-testcase.test # Before a testcase, run in record mode, save result file to var @@ -3103,6 +2931,7 @@ sub run_mysqltest ($) { $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; $ENV{'UDF_EXAMPLE_LIB'}= ($lib_udf_example ? basename($lib_udf_example) : ""); + $ENV{'MY_PERROR'}= $exe_perror; $ENV{'NDB_MGM'}= $exe_ndb_mgm; $ENV{'NDB_BACKUP_DIR'}= $path_ndb_data_dir; diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index afbff905699..d0058118e4c 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -232,7 +232,7 @@ a b delete from t1 where a=0; update t1 set a=NULL where b=6; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 4 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 4 update t1 set a=300 where b=7; SET SQL_MODE=''; insert into t1(a,b)values(NULL,8); @@ -274,7 +274,7 @@ a b delete from t1 where a=0; update t1 set a=NULL where b=13; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 9 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 9 update t1 set a=500 where b=14; select * from t1 order by b; a b diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index d60efa083e0..a07ca21652b 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -381,3 +381,14 @@ DROP TABLE t1; select cast(NULL as decimal(6)) as t1; t1 NULL +set names latin1; +select hex(cast('a' as char(2) binary)); +hex(cast('a' as char(2) binary)) +61 +select hex(cast('a' as binary(2))); +hex(cast('a' as binary(2))) +6100 +select hex(cast('a' as char(2) binary)); +hex(cast('a' as char(2) binary)) +61 +End of 5.0 tests diff --git a/mysql-test/r/compare.result b/mysql-test/r/compare.result index 6f667aabac0..da0ca8ddba1 100644 --- a/mysql-test/r/compare.result +++ b/mysql-test/r/compare.result @@ -42,3 +42,10 @@ CHAR(31) = '' '' = CHAR(31) SELECT CHAR(30) = '', '' = CHAR(30); CHAR(30) = '' '' = CHAR(30) 0 0 +create table t1 (a tinyint(1),b binary(1)); +insert into t1 values (0x01,0x01); +select * from t1 where a=b; +a b +select * from t1 where a=b and b=0x01; +a b +drop table if exists t1; diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index aa8c6d3d277..3f8083a0e20 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -13,7 +13,7 @@ Warnings: Note 1050 Table 't1' already exists insert into t1 values (""),(null); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'b' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2 select * from t1; b @@ -452,7 +452,7 @@ t2 CREATE TABLE `t2` ( `ifnull(h,h)` decimal(5,4) default NULL, `ifnull(i,i)` year(4) default NULL, `ifnull(j,j)` date default NULL, - `ifnull(k,k)` datetime NOT NULL default '0000-00-00 00:00:00', + `ifnull(k,k)` timestamp NOT NULL default '0000-00-00 00:00:00', `ifnull(l,l)` datetime default NULL, `ifnull(m,m)` varchar(1) default NULL, `ifnull(n,n)` varchar(3) default NULL, diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 3c87c1f4b92..f3e91a663b8 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5000,3 +5000,13 @@ insert t1 values (1),(2),(3),(4),(5); truncate table t1; affected rows: 0 drop table t1; +create table bug15205 (val int(11) default null) engine=csv; +create table bug15205_2 (val int(11) default null) engine=csv; +select * from bug15205; +ERROR HY000: Got error 1 from storage engine +select * from bug15205_2; +val +select * from bug15205; +val +drop table bug15205; +drop table bug15205_2; diff --git a/mysql-test/r/ctype_cp1250_ch.result b/mysql-test/r/ctype_cp1250_ch.result index 533bfb8cb53..b55849e4e12 100644 --- a/mysql-test/r/ctype_cp1250_ch.result +++ b/mysql-test/r/ctype_cp1250_ch.result @@ -42,3 +42,11 @@ id str 6 aaaaaa 7 aaaaaaa drop table t1; +set names cp1250; +create table t1 (a varchar(15) collate cp1250_czech_cs NOT NULL, primary key(a)); +insert into t1 values("abcdefghá"); +insert into t1 values("ááèè"); +select a from t1 where a like "abcdefghá"; +a +abcdefghá +drop table t1; diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index 996f6fa8645..4e145346081 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -248,3 +248,14 @@ select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1; rpad(c1,3,'ö') rpad('ö',3,c1) ßöö ößß drop table t1; +set names koi8r; +create table t1(a char character set cp1251 default _koi8r 0xFF); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) character set cp1251 default 'ÿ' +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1(a char character set latin1 default _cp1251 0xFF); +ERROR 42000: Invalid default value for 'a' +End of 4.1 tests diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 890cdfd5cfc..3b6bfa6d776 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -730,6 +730,45 @@ id MIN(s) 1 ZZZ 2 ZZZ DROP TABLE t1; +drop table if exists bug20536; +set names latin1; +create table bug20536 (id bigint not null auto_increment primary key, name +varchar(255) character set ucs2 not null); +insert into `bug20536` (`id`,`name`) values (1, _latin1 x'7465737431'), (2, "'test\\_2'"); +select md5(name) from bug20536; +md5(name) +f4b7ce8b45a20e3c4e84bef515d1525c +48d95db0d8305c2fe11548a3635c9385 +select sha1(name) from bug20536; +sha1(name) +e0b52f38deddb9f9e8d5336b153592794cb49baf +677d4d505355eb5b0549b865fcae4b7f0c28aef5 +select make_set(3, name, upper(name)) from bug20536; +make_set(3, name, upper(name)) +test1,TEST1 +'test\_2','TEST\_2' +select export_set(5, name, upper(name)) from bug20536; +export_set(5, name, upper(name)) +test1,TEST1,test1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1 +'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2' +select export_set(5, name, upper(name), ",", 5) from bug20536; +export_set(5, name, upper(name), ",", 5) +test1,TEST1,test1,TEST1,TEST1 +'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2' +select password(name) from bug20536; +password(name) +???????????????????? +???????????????????? +select old_password(name) from bug20536; +old_password(name) +???????? +???????? +select quote(name) from bug20536; +quote(name) +???????? +???????????????? +drop table bug20536; +End of 4.1 tests CREATE TABLE t1 (a varchar(64) character set ucs2, b decimal(10,3)); INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0); update t1 set b=a; @@ -765,3 +804,4 @@ blob 65535 65535 text 65535 65535 text 65535 32767 drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 934f56877ac..51f361349e6 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -924,6 +924,37 @@ NULL select ifnull(NULL, _utf8'string'); ifnull(NULL, _utf8'string') string +set names utf8; +create table t1 (s1 char(5) character set utf8 collate utf8_lithuanian_ci); +insert into t1 values ('I'),('K'),('Y'); +select * from t1 where s1 < 'K' and s1 = 'Y'; +s1 +I +Y +select * from t1 where 'K' > s1 and s1 = 'Y'; +s1 +I +Y +drop table t1; +create table t1 (s1 char(5) character set utf8 collate utf8_czech_ci); +insert into t1 values ('c'),('d'),('h'),('ch'),('CH'),('cH'),('Ch'),('i'); +select * from t1 where s1 > 'd' and s1 = 'CH'; +s1 +ch +CH +Ch +select * from t1 where 'd' < s1 and s1 = 'CH'; +s1 +ch +CH +Ch +select * from t1 where s1 = 'cH' and s1 <> 'ch'; +s1 +cH +select * from t1 where 'cH' = s1 and s1 <> 'ch'; +s1 +cH +drop table t1; create table t1 (a varchar(255)) default character set utf8; insert into t1 values (1.0); drop table t1; @@ -1066,6 +1097,18 @@ LENGTH(bug) 100 DROP TABLE t2; DROP TABLE t1; +CREATE TABLE t1 (item varchar(255)) default character set utf8; +INSERT INTO t1 VALUES (N'\\'); +INSERT INTO t1 VALUES (_utf8'\\'); +INSERT INTO t1 VALUES (N'Cote d\'Ivoire'); +INSERT INTO t1 VALUES (_utf8'Cote d\'Ivoire'); +SELECT item FROM t1 ORDER BY item; +item +Cote d'Ivoire +Cote d'Ivoire +\ +\ +DROP TABLE t1; SET NAMES utf8; DROP TABLE IF EXISTS t1; Warnings: @@ -1281,6 +1324,35 @@ id tid val 42749 72 VOLNÝ ADSL 44205 72 VOLNÝ ADSL DROP TABLE t1; +create table t1(a char(200) collate utf8_unicode_ci NOT NULL default '') +default charset=utf8 collate=utf8_unicode_ci; +insert into t1 values (unhex('65')), (unhex('C3A9')), (unhex('65')); +explain select distinct a from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary +select distinct a from t1; +a +e +explain select a from t1 group by a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort +select a from t1 group by a; +a +e +drop table t1; +set names utf8; +grant select on test.* to юзер_юзер@localhost; +user() +юзер_юзер@localhost +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; +create database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45; +use имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45; +select database(); +database() +имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45 +drop database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45; +use test; CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8; INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa'); SELECT id FROM t1; diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 08ed5fc6439..bbe3aee1fb0 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -449,6 +449,8 @@ create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:% str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2, str_to_date("2003-01-02", "%Y-%m-%d") as f3, str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5; +Warnings: +Warning 1265 Data truncated for column 'f4' at row 1 describe t1; Field Type Null Key Default Extra f1 datetime YES NULL @@ -458,7 +460,7 @@ f4 date YES NULL f5 time YES NULL select * from t1; f1 f2 f3 f4 f5 -2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00 +2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-00 58:00:00 drop table t1; create table t1 select "02 10" as a, "%d %H" as b; select str_to_date(a,b) from t1; diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 05f1c967e77..0946dc8f809 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -192,3 +192,13 @@ delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; select * from t3; a b drop table t1,t2,t3; +create table t1(a date not null); +insert into t1 values (0); +select * from t1 where a is null; +a +0000-00-00 +delete from t1 where a is null; +select count(*) from t1; +count(*) +0 +drop table t1; diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index a3d1e8bf3bb..86ab2141e2d 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -563,6 +563,17 @@ id IFNULL(dsc, '-') 2 line number two 3 line number three drop table t1; +CREATE TABLE t1 (a int primary key, b int); +INSERT INTO t1 (a,b) values (1,1), (2,3), (3,2); +explain SELECT DISTINCT a, b FROM t1 ORDER BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort +SELECT DISTINCT a, b FROM t1 ORDER BY b; +a b +1 1 +3 2 +2 3 +DROP TABLE t1; CREATE TABLE t1 ( ID int(11) NOT NULL auto_increment, x varchar(20) default NULL, diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 979e5d48871..d122dabc4ec 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -72,3 +72,16 @@ show tables; Tables_in_test t1 drop table t1; +drop database if exists mysqltest; +drop table if exists t1; +create table t1 (i int); +lock tables t1 read; +create database mysqltest; + drop table t1; +show open tables; + drop database mysqltest; +select 1; +1 +1 +unlock tables; +End of 5.0 tests diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 5d17afd8cfc..2b44fc8bd7e 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -967,6 +967,8 @@ CREATE TABLE federated.t1 ( `blurb` text default '', PRIMARY KEY (blurb_id)) DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'blurb' can't have a default value DROP TABLE IF EXISTS federated.t1; CREATE TABLE federated.t1 ( `blurb_id` int NOT NULL DEFAULT 0, @@ -975,6 +977,8 @@ PRIMARY KEY (blurb_id)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +Warnings: +Warning 1101 BLOB/TEXT column 'blurb' can't have a default value INSERT INTO federated.t1 VALUES (1, " MySQL supports a number of column types in several categories: numeric types, date and time types, and string (character) types. This chapter first gives an overview of these column types, and then provides a more detailed description of the properties of the types in each category, and a summary of the column type storage requirements. The overview is intentionally brief. The more detailed descriptions should be consulted for additional information about particular column types, such as the allowable formats in which you can specify values."); INSERT INTO federated.t1 VALUES (2, "All arithmetic is done using signed BIGINT or DOUBLE values, so you should not use unsigned big integers larger than 9223372036854775807 (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting a BIGINT value to a DOUBLE."); INSERT INTO federated.t1 VALUES (3, " A floating-point number. p represents the precision. It can be from 0 to 24 for a single-precision floating-point number and from 25 to 53 for a double-precision floating-point number. These types are like the FLOAT and DOUBLE types described immediately following. FLOAT(p) has the same range as the corresponding FLOAT and DOUBLE types, but the display size and number of decimals are undefined. "); @@ -1784,6 +1788,33 @@ length(a) 5000 drop table t1; drop table t1; +DROP TABLE IF EXISTS federated.test; +CREATE TABLE federated.test ( +`i` int(11) NOT NULL, +`j` int(11) NOT NULL, +`c` varchar(30) default NULL, +PRIMARY KEY (`i`,`j`), +UNIQUE KEY `i` (`i`,`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS federated.test1; +DROP TABLE IF EXISTS federated.test2; +create table federated.test1 ( +i int not null, +j int not null, +c varchar(30), +primary key (i,j), +unique key (i, c)) +engine = federated +connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/test'; +create table federated.test2 ( +i int default null, +j int not null, +c varchar(30), +key (i)) +engine = federated +connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/test'; +drop table federated.test1, federated.test2; +drop table federated.test; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; DROP TABLE IF EXISTS federated.t1; diff --git a/mysql-test/r/fulltext_distinct.result b/mysql-test/r/fulltext_distinct.result index de0668ff28c..7fd42fab646 100644 --- a/mysql-test/r/fulltext_distinct.result +++ b/mysql-test/r/fulltext_distinct.result @@ -8,6 +8,8 @@ KEY kt(tag), KEY kv(value(15)), FULLTEXT KEY kvf(value) ) ENGINE=MyISAM; +Warnings: +Warning 1101 BLOB/TEXT column 'value' can't have a default value CREATE TABLE t2 ( id_t2 mediumint unsigned NOT NULL default '0', id_t1 mediumint unsigned NOT NULL default '0', diff --git a/mysql-test/r/fulltext_update.result b/mysql-test/r/fulltext_update.result index 5d3f95b318c..4a615c88fdd 100644 --- a/mysql-test/r/fulltext_update.result +++ b/mysql-test/r/fulltext_update.result @@ -9,6 +9,8 @@ name VARCHAR(80) DEFAULT '' NOT NULL, FULLTEXT(url,description,shortdesc,longdesc), PRIMARY KEY(gnr) ); +Warnings: +Warning 1101 BLOB/TEXT column 'longdesc' can't have a default value insert into test (url,shortdesc,longdesc,description,name) VALUES ("http:/test.at", "kurz", "lang","desc", "name"); insert into test (url,shortdesc,longdesc,description,name) VALUES diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index e3d31566741..00d5ebfc351 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -79,3 +79,31 @@ uncompress(a) uncompressed_length(a) NULL NULL a 1 drop table t1; +create table t1 (a varchar(32) not null); +insert into t1 values ('foo'); +explain select * from t1 where uncompress(a) is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Error 1259 ZLIB: Input data corrupted +select * from t1 where uncompress(a) is null; +a +foo +Warnings: +Error 1259 ZLIB: Input data corrupted +explain select *, uncompress(a) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +select *, uncompress(a) from t1; +a uncompress(a) +foo NULL +Warnings: +Error 1259 ZLIB: Input data corrupted +select *, uncompress(a), uncompress(a) is null from t1; +a uncompress(a) uncompress(a) is null +foo NULL 1 +Warnings: +Error 1259 ZLIB: Input data corrupted +Error 1259 ZLIB: Input data corrupted +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index d8a539da3fe..dc09a68682c 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -641,3 +641,16 @@ select charset(group_concat(c1 order by c2)) from t1; charset(group_concat(c1 order by c2)) latin1 drop table t1; +CREATE TABLE t1 (a INT(10), b LONGTEXT, PRIMARY KEY (a)); +SET GROUP_CONCAT_MAX_LEN = 20000000; +INSERT INTO t1 VALUES (1,REPEAT(CONCAT('A',CAST(CHAR(0) AS BINARY),'B'), 40000)); +INSERT INTO t1 SELECT a + 1, b FROM t1; +SELECT a, CHAR_LENGTH(b) FROM t1; +a CHAR_LENGTH(b) +1 120000 +2 120000 +SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1; +CHAR_LENGTH( GROUP_CONCAT(b) ) +240001 +SET GROUP_CONCAT_MAX_LEN = 1024; +DROP TABLE t1; diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index f693c6190d5..f57b4ad6ce9 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -988,3 +988,28 @@ SUM(a) 6 DROP TABLE t1; set div_precision_increment= @sav_dpi; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT); +INSERT INTO t1 VALUES (1,1), (2,2); +CREATE TABLE t2 (a INT PRIMARY KEY, b INT); +INSERT INTO t2 VALUES (1,1), (3,3); +SELECT SQL_NO_CACHE +(SELECT SUM(c.a) FROM t1 ttt, t2 ccc +WHERE ttt.a = ccc.b AND ttt.a = t.a GROUP BY ttt.a) AS minid +FROM t1 t, t2 c WHERE t.a = c.b; +minid +NULL +DROP TABLE t1,t2; +create table t1 select variance(0); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `variance(0)` double(8,4) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 select stddev(0); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `stddev(0)` double(8,4) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 33e642c74c4..f0262acd71e 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -87,6 +87,10 @@ SELECT IS_USED_LOCK('bug16501'); IS_USED_LOCK('bug16501') NULL DROP TABLE t1; +select export_set(3, _latin1'foo', _utf8'bar', ',', 4); +export_set(3, _latin1'foo', _utf8'bar', ',', 4) +foo,foo,bar,bar +End of 4.1 tests create table t1 as select uuid(), length(uuid()); show create table t1; Table Create Table @@ -130,3 +134,4 @@ timediff(b, a) >= '00:00:03' drop table t2; drop table t1; set global query_cache_size=default; +End of 5.0 tests diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index aebf3596751..14da630f61e 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1056,6 +1056,34 @@ a c abc abc abc xyz xyz xyz DROP TABLE t1; +CREATE TABLE t1 (s varchar(10)); +INSERT INTO t1 VALUES ('yadda'), ('yaddy'); +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(s) > 'ab'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(`test`.`t1`.`s`) > _latin1'ab') +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM('y' FROM s) > 'ab'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both _latin1'y' from `test`.`t1`.`s`) > _latin1'ab') +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(LEADING 'y' FROM s) > 'ab'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(leading _latin1'y' from `test`.`t1`.`s`) > _latin1'ab') +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(TRAILING 'y' FROM s) > 'ab'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(trailing _latin1'y' from `test`.`t1`.`s`) > _latin1'ab') +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(BOTH 'y' FROM s) > 'ab'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +Warnings: +Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both _latin1'y' from `test`.`t1`.`s`) > _latin1'ab') +DROP TABLE t1; End of 4.1 tests create table t1 (d decimal default null); insert into t1 values (null); diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index db696f61fed..dc6a4561531 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -667,6 +667,78 @@ timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4; a1 a2 a3 a4 28 28 29 29 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:27'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:27') +0 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:28'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:28') +1 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:29'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:29') +1 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:27'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:27') +1 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:28'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:28') +2 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:29'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:29') +2 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:27'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:27') +0 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:28'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:28') +1 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:29'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:29') +1 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:27'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:27') +1 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:28'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:28') +2 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:29'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:29') +2 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:27'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:27') +0 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:28'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:28') +1 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:29'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:29') +1 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:27'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:27') +1 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:28'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:28') +2 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:29'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:29') +2 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:27'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:27') +0 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:28'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:28') +1 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:29'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:29') +1 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:27'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:27') +1 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:28'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:28') +2 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29') +2 select date_add(time,INTERVAL 1 SECOND) from t1; date_add(time,INTERVAL 1 SECOND) NULL @@ -819,6 +891,27 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H); +H +120 +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H); +H +120 +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H); +H +05 +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H); +H +5 +End of 4.1 tests explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; id select_type table type possible_keys key key_len ref rows Extra @@ -960,3 +1053,15 @@ id day id day 3 2005-07-01 3 2005-07-15 DROP TABLE t1,t2; set time_zone= @@global.time_zone; +SET NAMES latin1; +SET character_set_results = NULL; +SHOW VARIABLES LIKE 'character_set_results'; +Variable_name Value +character_set_results +CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); +INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); +SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; +fmtddate field2 +Sep-4 12:00AM abcd +DROP TABLE testBug8868; +SET NAMES DEFAULT; diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index 28c59053435..b283d64395d 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -804,6 +804,8 @@ INSERT INTO t2 SELECT GeomFromText(st) FROM t1; ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field drop table t1, t2; CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`(32))) ENGINE=MyISAM DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'geometry' can't have a default value INSERT INTO t1 (geometry) VALUES (PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000 -66.8158332999, -18.7186111000 -66.8102777000, -18.7211111000 -66.9269443999, @@ -820,6 +822,8 @@ CREATE TABLE t1 ( c1 geometry NOT NULL default '', SPATIAL KEY i1 (c1(32)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'c1' can't have a default value INSERT INTO t1 (c1) VALUES ( PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000 -66.8158332999, @@ -834,6 +838,8 @@ CREATE TABLE t1 ( c1 geometry NOT NULL default '', SPATIAL KEY i1 (c1(32)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'c1' can't have a default value INSERT INTO t1 (c1) VALUES ( PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000 -66.8158332999, diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 7a0f689df36..46aecde2cc5 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -574,15 +574,17 @@ INSERT INTO t1 VALUES(GeomFromText('POINT(367894677 368542487)')); INSERT INTO t1 VALUES(GeomFromText('POINT(580848489 219587743)')); INSERT INTO t1 VALUES(GeomFromText('POINT(11247614 782797569)')); drop table t1; -create table t1 select POINT(1,3); +create table t1 select GeomFromWKB(POINT(1,3)); show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `POINT(1,3)` longblob NOT NULL + `GeomFromWKB(POINT(1,3))` geometry NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE `t1` (`object_id` bigint(20) unsigned NOT NULL default '0', `geo` geometry NOT NULL default '') ENGINE=MyISAM ; +Warnings: +Warning 1101 BLOB/TEXT column 'geo' can't have a default value insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363 36.305435,-114.992394 36.305202,-114.991219 36.305975,-114.991163 36.306845,-114.989432 36.309452,-114.978275 36.312642,-114.977363 @@ -704,3 +706,8 @@ Catalog Database Table Table_alias Column Column_alias Type Length Max length Is def asbinary(g) 252 8192 0 Y 128 0 63 asbinary(g) drop table t1; +create table t1 select GeomFromText('point(1 1)'); +desc t1; +Field Type Null Key Default Extra +GeomFromText('point(1 1)') geometry NO +drop table t1; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 3f3325354ee..2f417a41652 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -426,6 +426,7 @@ revoke all on mysqltest_2.t1 from mysqltest_3@localhost; revoke all on mysqltest_2.t2 from mysqltest_3@localhost; grant all on mysqltest_2.* to mysqltest_3@localhost; grant select on *.* to mysqltest_3@localhost; +grant select on mysqltest_2.t1 to mysqltest_3@localhost; flush privileges; use mysqltest_1; update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600; @@ -525,7 +526,7 @@ Db char(64) NO PRI User char(16) NO PRI Table_name char(64) NO PRI Grantor char(77) NO MUL -Timestamp timestamp YES CURRENT_TIMESTAMP +Timestamp timestamp NO CURRENT_TIMESTAMP Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view') NO Column_priv set('Select','Insert','Update','References') NO use test; @@ -867,3 +868,106 @@ insert into mysql.user select * from t2; flush privileges; drop table t2; drop table t1; +CREATE DATABASE mysqltest3; +use mysqltest3; +CREATE TABLE t_nn (c1 INT); +CREATE VIEW v_nn AS SELECT * FROM t_nn; +CREATE DATABASE mysqltest2; +use mysqltest2; +CREATE TABLE t_nn (c1 INT); +CREATE VIEW v_nn AS SELECT * FROM t_nn; +CREATE VIEW v_yn AS SELECT * FROM t_nn; +CREATE VIEW v_gy AS SELECT * FROM t_nn; +CREATE VIEW v_ny AS SELECT * FROM t_nn; +CREATE VIEW v_yy AS SELECT * FROM t_nn WHERE c1=55; +GRANT SHOW VIEW ON mysqltest2.v_ny TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +GRANT SELECT ON mysqltest2.v_yn TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +GRANT SELECT ON mysqltest2.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +GRANT SHOW VIEW,SELECT ON mysqltest2.v_yy TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +SHOW CREATE VIEW mysqltest2.v_nn; +ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' +SHOW CREATE TABLE mysqltest2.v_nn; +ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' +SHOW CREATE VIEW mysqltest2.v_yn; +ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_yn' +SHOW CREATE TABLE mysqltest2.v_yn; +ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_yn' +SHOW CREATE TABLE mysqltest2.v_ny; +View Create View +v_ny CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` +SHOW CREATE VIEW mysqltest2.v_ny; +View Create View +v_ny CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` +SHOW CREATE TABLE mysqltest3.t_nn; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn' +SHOW CREATE VIEW mysqltest3.t_nn; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn' +SHOW CREATE VIEW mysqltest3.v_nn; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' +SHOW CREATE TABLE mysqltest3.v_nn; +ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v_nn' +SHOW CREATE TABLE mysqltest2.t_nn; +Table Create Table +t_nn CREATE TABLE `t_nn` ( + `c1` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW CREATE VIEW mysqltest2.t_nn; +ERROR HY000: 'mysqltest2.t_nn' is not VIEW +SHOW CREATE VIEW mysqltest2.v_yy; +View Create View +v_yy CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where (`mysqltest2`.`t_nn`.`c1` = 55) +SHOW CREATE TABLE mysqltest2.v_yy; +View Create View +v_yy CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where (`mysqltest2`.`t_nn`.`c1` = 55) +SHOW CREATE TABLE mysqltest2.v_nn; +View Create View +v_nn CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_nn` AS select `t_nn`.`c1` AS `c1` from `t_nn` +SHOW CREATE VIEW mysqltest2.v_nn; +View Create View +v_nn CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_nn` AS select `t_nn`.`c1` AS `c1` from `t_nn` +SHOW CREATE TABLE mysqltest2.t_nn; +Table Create Table +t_nn CREATE TABLE `t_nn` ( + `c1` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +SHOW CREATE VIEW mysqltest2.t_nn; +ERROR HY000: 'mysqltest2.t_nn' is not VIEW +DROP VIEW mysqltest2.v_nn; +DROP VIEW mysqltest2.v_yn; +DROP VIEW mysqltest2.v_ny; +DROP VIEW mysqltest2.v_yy; +DROP TABLE mysqltest2.t_nn; +DROP DATABASE mysqltest2; +DROP VIEW mysqltest3.v_nn; +DROP TABLE mysqltest3.t_nn; +DROP DATABASE mysqltest3; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost'; +DROP USER 'mysqltest_1'@'localhost'; +use test; +create user mysqltest1_thisisreallytoolong; +ERROR HY000: String 'mysqltest1_thisisreallytoolong' is too long for user name (should be no longer than 16) +GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +GRANT CREATE ON mysqltest.* TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +REVOKE CREATE ON mysqltest.* FROM 1234567890abcdefGHIKL@localhost; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +REVOKE CREATE ON mysqltest.* FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +GRANT CREATE ON t1 TO 1234567890abcdefGHIKL@localhost; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +GRANT CREATE ON t1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +REVOKE CREATE ON t1 FROM 1234567890abcdefGHIKL@localhost; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +REVOKE CREATE ON t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +GRANT EXECUTE ON PROCEDURE p1 TO 1234567890abcdefGHIKL@localhost; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +GRANT EXECUTE ON PROCEDURE p1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +End of 5.0 tests diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index eb9e95c40bd..2700426257b 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -118,6 +118,16 @@ flush privileges; drop user mysqltest_3@host3; drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4, mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7; +create database mysqltest_1; +grant select, insert, update on `mysqltest\_1`.* to mysqltest_1@localhost; +set sql_log_off = 1; +ERROR 42000: Access denied; you need the SUPER privilege for this operation +set sql_log_bin = 0; +ERROR 42000: Access denied; you need the SUPER privilege for this operation +delete from mysql.user where user like 'mysqltest\_1'; +delete from mysql.db where user like 'mysqltest\_1'; +drop database mysqltest_1; +flush privileges; set sql_mode='maxdb'; drop table if exists t1, t2; create table t1(c1 int); diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 7bc886022cc..57cb09fe44c 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -796,3 +796,37 @@ aaa show warnings; Level Code Message drop table t1, t2; +CREATE TABLE t1 (a tinyint(3), b varchar(255), PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1,'-----'), (6,'Allemagne'), (17,'Autriche'), +(25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France'); +CREATE TABLE t2 (a tinyint(3), b tinyint(3), PRIMARY KEY (a), KEY b (b)); +INSERT INTO t2 VALUES (1,1), (2,1), (6,6), (18,17), (15,25), (16,25), +(17,25), (10,54), (5,62),(3,68); +CREATE VIEW v1 AS select t1.a, concat(t1.b,'') AS b, t1.b as real_b from t1; +explain +SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1 +where t2.b=v1.a GROUP BY t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 index b b 2 NULL 10 Using index +1 PRIMARY t1 eq_ref PRIMARY PRIMARY 1 test.t2.b 1 +SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1 +where t2.b=v1.a GROUP BY t2.b; +a b real_b +1 ----- ----- +6 Allemagne Allemagne +17 Autriche Autriche +25 Belgique Belgique +54 Danemark Danemark +62 Espagne Espagne +68 France France +DROP VIEW v1; +DROP TABLE t1,t2; +CREATE TABLE t1 (a INT, b INT, KEY(a)); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4); +EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 4 +EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort +DROP TABLE t1; diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index d62586dba85..fe6f7c4ca55 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2099,3 +2099,46 @@ SOUTH EAST SOUTH EAST SOUTH WEST SOUTH WEST WESTERN WESTERN DROP TABLE t1; +CREATE TABLE t1 (id1 INT, id2 INT); +CREATE TABLE t2 (id2 INT, id3 INT, id5 INT); +CREATE TABLE t3 (id3 INT, id4 INT); +CREATE TABLE t4 (id4 INT); +CREATE TABLE t5 (id5 INT, id6 INT); +CREATE TABLE t6 (id6 INT); +INSERT INTO t1 VALUES(1,1); +INSERT INTO t2 VALUES(1,1,1); +INSERT INTO t3 VALUES(1,1); +INSERT INTO t4 VALUES(1); +INSERT INTO t5 VALUES(1,1); +INSERT INTO t6 VALUES(1); +SELECT * FROM +t1 +NATURAL JOIN +(t2 JOIN (t3 NATURAL JOIN t4, t5 NATURAL JOIN t6) +ON (t3.id3 = t2.id3 AND t5.id5 = t2.id5)); +id2 id1 id3 id5 id4 id3 id6 id5 +1 1 1 1 1 1 1 1 +SELECT * FROM +t1 +NATURAL JOIN +(((t3 NATURAL JOIN t4) join (t5 NATURAL JOIN t6) on t3.id4 = t5.id5) JOIN t2 +ON (t3.id3 = t2.id3 AND t5.id5 = t2.id5)); +id2 id1 id4 id3 id6 id5 id3 id5 +1 1 1 1 1 1 1 1 +SELECT * FROM t1 NATURAL JOIN ((t3 join (t5 NATURAL JOIN t6)) JOIN t2); +id2 id1 id3 id4 id6 id5 id3 id5 +1 1 1 1 1 1 1 1 +SELECT * FROM +(t2 JOIN (t3 NATURAL JOIN t4, t5 NATURAL JOIN t6) +ON (t3.id3 = t2.id3 AND t5.id5 = t2.id5)) +NATURAL JOIN +t1; +id2 id3 id5 id4 id3 id6 id5 id1 +1 1 1 1 1 1 1 1 +SELECT * FROM +(t2 JOIN ((t3 NATURAL JOIN t4) join (t5 NATURAL JOIN t6))) +NATURAL JOIN +t1; +id2 id3 id5 id4 id3 id6 id5 id1 +1 1 1 1 1 1 1 1 +DROP TABLE t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/r/have_perror.require b/mysql-test/r/have_perror.require new file mode 100644 index 00000000000..260687c87f0 --- /dev/null +++ b/mysql-test/r/have_perror.require @@ -0,0 +1,2 @@ +have_perror +1 diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 4b05e8f44e1..5b9c7f2244f 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -246,6 +246,41 @@ DELETE from t1 where a < 100; SELECT * from t1; a DROP TABLE t1; +create table t1(a int not null, key using btree(a)) engine=heap; +insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3); +select a from t1 where a > 2 order by a; +a +3 +3 +3 +3 +delete from t1 where a < 4; +select a from t1 order by a; +a +insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3); +select a from t1 where a > 4 order by a; +a +delete from t1 where a > 4; +select a from t1 order by a; +a +1 +1 +2 +2 +2 +3 +3 +3 +3 +select a from t1 where a > 3 order by a; +a +delete from t1 where a >= 2; +select a from t1 order by a; +a +1 +1 +drop table t1; +End of 4.1 tests CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; INSERT INTO t1 VALUES(0); SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; @@ -259,3 +294,4 @@ DROP TABLE t1; CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY; INSERT INTO t1 VALUES(NULL),(NULL); DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/im_daemon_life_cycle.result b/mysql-test/r/im_daemon_life_cycle.result index ea27fcb6db1..b805bdc9166 100644 --- a/mysql-test/r/im_daemon_life_cycle.result +++ b/mysql-test/r/im_daemon_life_cycle.result @@ -1,4 +1,6 @@ -Success: the process has been started. +SHOW VARIABLES LIKE 'server_id'; +Variable_name Value +server_id 1 SHOW INSTANCES; instance_name status mysqld1 online diff --git a/mysql-test/r/im_life_cycle.result b/mysql-test/r/im_life_cycle.result index a9f78aea7d3..69f6bb5a490 100644 --- a/mysql-test/r/im_life_cycle.result +++ b/mysql-test/r/im_life_cycle.result @@ -1,8 +1,6 @@ - --------------------------------------------------------------------- --- 1.1.1. --------------------------------------------------------------------- -Success: the process has been started. +SHOW VARIABLES LIKE 'server_id'; +Variable_name Value +server_id 1 SHOW INSTANCES; instance_name status mysqld1 online @@ -40,10 +38,6 @@ ERROR HY000: Bad instance name. Check that the instance with such a name exists -------------------------------------------------------------------- -- 1.1.6. -------------------------------------------------------------------- -SHOW INSTANCES; -instance_name status -mysqld1 online -mysqld2 offline Killing the process... Sleeping... Success: the process was restarted. @@ -74,3 +68,6 @@ START INSTANCE mysqld1,mysqld2,mysqld3; ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use STOP INSTANCE mysqld1,mysqld2,mysqld3; ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use +STOP INSTANCE mysqld2; +ERROR HY000: Cannot stop instance. Perhaps the instance is not started, or was started manually, so IM cannot find the pidfile. +End of 5.0 tests diff --git a/mysql-test/r/im_options_set.result b/mysql-test/r/im_options_set.result index 5e6c740624e..f7b7e8eaef7 100644 --- a/mysql-test/r/im_options_set.result +++ b/mysql-test/r/im_options_set.result @@ -1,8 +1,10 @@ -server_id = 1 -server_id = 2 SHOW VARIABLES LIKE 'server_id'; Variable_name Value server_id 1 +SHOW INSTANCES; +instance_name status +mysqld1 online +mysqld2 offline SET mysqld1.server_id = 11; server_id =11 server_id = 2 diff --git a/mysql-test/r/im_options_unset.result b/mysql-test/r/im_options_unset.result index bf54025edb7..2ab775e611a 100644 --- a/mysql-test/r/im_options_unset.result +++ b/mysql-test/r/im_options_unset.result @@ -1,8 +1,10 @@ -server_id = 1 -server_id = 2 SHOW VARIABLES LIKE 'server_id'; Variable_name Value server_id 1 +SHOW INSTANCES; +instance_name status +mysqld1 online +mysqld2 offline UNSET mysqld1.server_id; server_id = 2 SHOW VARIABLES LIKE 'server_id'; diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result index e6a5e007ed4..f671089d31d 100644 --- a/mysql-test/r/im_utils.result +++ b/mysql-test/r/im_utils.result @@ -1,4 +1,6 @@ -Success: the process has been started. +SHOW VARIABLES LIKE 'server_id'; +Variable_name Value +server_id 1 SHOW INSTANCES; instance_name status mysqld1 online diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index a2feba7ad5d..652af1c8387 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1170,3 +1170,73 @@ f1() DROP FUNCTION f1; DROP PROCEDURE p1; DROP USER mysql_bug20230@localhost; +SELECT t.table_name, c1.column_name +FROM information_schema.tables t +INNER JOIN +information_schema.columns c1 +ON t.table_schema = c1.table_schema AND +t.table_name = c1.table_name +WHERE t.table_schema = 'information_schema' AND +c1.ordinal_position = +( SELECT COALESCE(MIN(c2.ordinal_position),1) +FROM information_schema.columns c2 +WHERE c2.table_schema = t.table_schema AND +c2.table_name = t.table_name AND +c2.column_name LIKE '%SCHEMA%' + ); +table_name column_name +CHARACTER_SETS CHARACTER_SET_NAME +COLLATIONS COLLATION_NAME +COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME +COLUMNS TABLE_SCHEMA +COLUMN_PRIVILEGES TABLE_SCHEMA +KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +ROUTINES ROUTINE_SCHEMA +SCHEMATA SCHEMA_NAME +SCHEMA_PRIVILEGES TABLE_SCHEMA +STATISTICS TABLE_SCHEMA +TABLES TABLE_SCHEMA +TABLE_CONSTRAINTS CONSTRAINT_SCHEMA +TABLE_PRIVILEGES TABLE_SCHEMA +TRIGGERS TRIGGER_SCHEMA +USER_PRIVILEGES GRANTEE +VIEWS TABLE_SCHEMA +SELECT t.table_name, c1.column_name +FROM information_schema.tables t +INNER JOIN +information_schema.columns c1 +ON t.table_schema = c1.table_schema AND +t.table_name = c1.table_name +WHERE t.table_schema = 'information_schema' AND +c1.ordinal_position = +( SELECT COALESCE(MIN(c2.ordinal_position),1) +FROM information_schema.columns c2 +WHERE c2.table_schema = 'information_schema' AND +c2.table_name = t.table_name AND +c2.column_name LIKE '%SCHEMA%' + ); +table_name column_name +CHARACTER_SETS CHARACTER_SET_NAME +COLLATIONS COLLATION_NAME +COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME +COLUMNS TABLE_SCHEMA +COLUMN_PRIVILEGES TABLE_SCHEMA +KEY_COLUMN_USAGE CONSTRAINT_SCHEMA +ROUTINES ROUTINE_SCHEMA +SCHEMATA SCHEMA_NAME +SCHEMA_PRIVILEGES TABLE_SCHEMA +STATISTICS TABLE_SCHEMA +TABLES TABLE_SCHEMA +TABLE_CONSTRAINTS CONSTRAINT_SCHEMA +TABLE_PRIVILEGES TABLE_SCHEMA +TRIGGERS TRIGGER_SCHEMA +USER_PRIVILEGES GRANTEE +VIEWS TABLE_SCHEMA +SELECT MAX(table_name) FROM information_schema.tables; +MAX(table_name) +VIEWS +SELECT table_name from information_schema.tables +WHERE table_name=(SELECT MAX(table_name) +FROM information_schema.tables); +table_name +VIEWS diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index 61a10c5f72c..40773a7afc1 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -97,3 +97,50 @@ v2 VIEW View 'test.v2' references invalid table(s) or column(s) or function(s) o drop function f1; drop function f2; drop view v1, v2; +create database testdb_1; +create user testdb_1@localhost; +grant all on testdb_1.* to testdb_1@localhost with grant option; +create user testdb_2@localhost; +grant all on test.* to testdb_2@localhost with grant option; +use testdb_1; +create table t1 (f1 char(4)); +create view v1 as select f1 from t1; +grant insert on v1 to testdb_2@localhost; +create table t3 (f1 char(4), f2 char(4)); +create view v3 as select f1,f2 from t3; +grant insert(f1), insert(f2) on v3 to testdb_2@localhost; +create view v2 as select f1 from testdb_1.v1; +create view v4 as select f1,f2 from testdb_1.v3; +revoke insert(f1) on v3 from testdb_2@localhost; +show create view v4; +ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table +show fields from v4; +ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table +show fields from v2; +Field Type Null Key Default Extra +f1 char(4) YES NULL +show fields from testdb_1.v1; +Field Type Null Key Default Extra +f1 char(4) YES NULL +show create view v2; +View Create View +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1` +show create view testdb_1.v1; +ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'v1' +select table_name from information_schema.columns a +where a.table_name = 'v2'; +table_name +v2 +select view_definition from information_schema.views a +where a.table_name = 'v2'; +view_definition +/* ALGORITHM=UNDEFINED */ select `v1`.`f1` AS `f1` from `testdb_1`.`v1` +select view_definition from information_schema.views a +where a.table_name = 'testdb_1.v1'; +view_definition +select * from v2; +ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +drop view testdb_1.v1,v2, testdb_1.v3, v4; +drop database testdb_1; +drop user testdb_1@localhost; +drop user testdb_2@localhost; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 77046cc1fd1..1d1f26e4b01 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1473,8 +1473,8 @@ Error 1146 Table 'test.t4' doesn't exist drop table t1,t2,t3; create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb; insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt'); -select name2 from t1 union all select name from t1 union all select id from t1; -name2 +select trim(name2) from t1 union all select trim(name) from t1 union all select trim(id) from t1; +trim(name2) fff sss ttt diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index bf0c4ff1f42..e7d097a1d2f 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -83,6 +83,27 @@ b a 3 3 3 3 DROP TABLE t1, t2, t3; +CREATE TABLE `t1` (`id1` INT) ; +INSERT INTO `t1` (`id1`) VALUES (1),(5),(2); +CREATE TABLE `t2` ( +`id1` INT, +`id2` INT NOT NULL, +`id3` INT, +`id4` INT NOT NULL, +UNIQUE (`id2`,`id4`), +KEY (`id1`) +) ENGINE=InnoDB; +INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES +(1,1,1,0), +(1,1,2,1), +(5,1,2,2), +(6,1,2,3), +(1,2,2,2), +(1,2,1,1); +SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2); +id1 +2 +DROP TABLE t1, t2; create table t1m (a int) engine=myisam; create table t1i (a int) engine=innodb; create table t2m (a int) engine=myisam; @@ -297,3 +318,22 @@ explain select distinct f1, f2 from t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary drop table t1; +CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), +INDEX (name)) ENGINE=InnoDB; +CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), +FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); +INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); +EXPLAIN +SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id +WHERE t1.name LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index +1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index +EXPLAIN +SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id +WHERE t1.name LIKE 'A%' OR FALSE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where +DROP TABLE t1,t2; diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 82fad8e912c..80723d68b5a 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -63,7 +63,7 @@ insert into t1 values(NULL); ERROR 23000: Column 'id' cannot be null insert into t1 values (1), (NULL), (2); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'id' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'id' at row 2 select * from t1; id 1 diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 3e2721fc09a..0af48d27cd5 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -606,8 +606,8 @@ NULL 2 100 create table t2(No int not null, Field int not null, Count int not null); insert into t2 Select null, Field, Count From t1 Where Month=20030901 and Type=2; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'No' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'No' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'No' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'No' at row 2 select * from t2; No Field Count 0 1 100 @@ -695,6 +695,16 @@ CREATE TABLE t2 (z int, y int); CREATE TABLE t3 (a int, b int); INSERT INTO t3 (SELECT x, y FROM t1 JOIN t2 USING (y) WHERE z = 1); DROP TABLE IF EXISTS t1,t2,t3; +CREATE DATABASE bug21774_1; +CREATE DATABASE bug21774_2; +CREATE TABLE bug21774_1.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_2.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_1.t2(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +INSERT INTO bug21774_2.t1 SELECT t1.* FROM bug21774_1.t1; +use bug21774_1; +INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1; +DROP DATABASE bug21774_1; +DROP DATABASE bug21774_2; CREATE DATABASE meow; CREATE TABLE table_target ( mexs_id CHAR(8), messzeit TIMESTAMP, PRIMARY KEY (mexs_id)); CREATE TABLE table_target2 ( mexs_id CHAR(8), messzeit TIMESTAMP, PRIMARY KEY (mexs_id)); diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index eae023813b5..2d9652ff0e3 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -598,6 +598,8 @@ id int(11) DEFAULT '0' NOT NULL, name tinytext DEFAULT '' NOT NULL, UNIQUE id (id) ); +Warnings: +Warning 1101 BLOB/TEXT column 'name' can't have a default value INSERT INTO t1 VALUES (1,'yes'),(2,'no'); CREATE TABLE t2 ( id int(11) DEFAULT '0' NOT NULL, @@ -735,7 +737,7 @@ explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from (t2 s left join t1 m on m.match_id = 1) order by m.match_id desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE s ALL NULL NULL NULL NULL 10 +1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort 1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from (t2 s left join t1 m on m.match_id = 1) @@ -1135,25 +1137,6 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 DROP TABLE t1,t2; -CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), -INDEX (name)) ENGINE=InnoDB; -CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), -FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); -INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); -EXPLAIN -SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id -WHERE t1.name LIKE 'A%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index -1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index -EXPLAIN -SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id -WHERE t1.name LIKE 'A%' OR FALSE; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where -DROP TABLE t1,t2; DROP VIEW IF EXISTS v1,v2; DROP TABLE IF EXISTS t1,t2; CREATE TABLE t1 (a int); diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index 0174ea45935..eea884e4294 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -159,8 +159,8 @@ CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT, UNIQUE (c,i)); INSERT INTO t1 (c) VALUES (NULL),(NULL); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 2 SELECT * FROM t1; c i 1 diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result index 1e38f762dd1..be2776ef533 100644 --- a/mysql-test/r/limit.result +++ b/mysql-test/r/limit.result @@ -76,3 +76,17 @@ a a 1 drop table t1; +create table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6),(7); +explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using temporary +select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +c +7 +explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using temporary +select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +c +28 diff --git a/mysql-test/r/loaddata_autocom_innodb.result b/mysql-test/r/loaddata_autocom_innodb.result new file mode 100644 index 00000000000..10da6b5dde7 --- /dev/null +++ b/mysql-test/r/loaddata_autocom_innodb.result @@ -0,0 +1,21 @@ +SET SESSION STORAGE_ENGINE = InnoDB; +drop table if exists t1; +create table t1 (a text, b text); +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +commit; +select count(*) from t1; +count(*) +4 +truncate table t1; +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +rollback; +select count(*) from t1; +count(*) +0 +drop table t1; diff --git a/mysql-test/r/loaddata_autocom_ndb.result b/mysql-test/r/loaddata_autocom_ndb.result new file mode 100644 index 00000000000..94e5f825fa2 --- /dev/null +++ b/mysql-test/r/loaddata_autocom_ndb.result @@ -0,0 +1,23 @@ +SET SESSION STORAGE_ENGINE = ndbcluster; +drop table if exists t1; +create table t1 (a text, b text); +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +commit; +select count(*) from t1; +count(*) +4 +truncate table t1; +start transaction; +load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by ''''; +Warnings: +Warning 1261 Row 3 doesn't contain data for all columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +4 +drop table t1; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index d70366a7589..7dbff4beca5 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -59,16 +59,16 @@ database() test unlock tables; drop table t1; -ソ -ソ +ƒ\ +ƒ\ c_cp932 +ƒ\ +ƒ\ +ƒ\ ソ ソ -ソ -ソ -ソ -ソ -ソ +ƒ\ +ƒ\ +----------------------+------------+--------+ | concat('>',col1,'<') | col2 | col3 | +----------------------+------------+--------+ @@ -85,6 +85,12 @@ c_cp932 | NULL | NULL | Τη γλώσσα | | NULL | NULL | á›–áš´ áš·á›–á› | +------+------+---------------------------+ +i j k +NULL 1 NULL +Field Type Null Key Default Extra +i int(11) YES NULL +j int(11) NO +k int(11) YES NULL +------+---+------+ | i | j | k | +------+---+------+ @@ -97,6 +103,10 @@ c_cp932 | j | int(11) | NO | | | | | k | int(11) | YES | | NULL | | +-------+---------+------+-----+---------+-------+ +i s1 +1 x +2 NULL +3 +------+------+ | i | s1 | +------+------+ @@ -104,4 +114,29 @@ c_cp932 | 2 | NULL | | 3 | | +------+------+ +unhex('zz') +NULL ++-------------+ +| unhex('zz') | ++-------------+ +| NULL | ++-------------+ +create table t1(a int, b varchar(255), c int); +Field Type Null Key Default Extra +a int(11) YES NULL +b varchar(255) YES NULL +c int(11) YES NULL +Field Type Null Key Default Extra +a int(11) YES NULL +b varchar(255) YES NULL +c int(11) YES NULL +drop table t1; +1 +1 +ERROR 1064 (42000) at line 3: 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 +ERROR at line 1: USE must be followed by a database name +\ +\\ +'; +'; End of 5.0 tests diff --git a/mysql-test/r/mysql_client.result b/mysql-test/r/mysql_client.result deleted file mode 100644 index 87d09428ff6..00000000000 --- a/mysql-test/r/mysql_client.result +++ /dev/null @@ -1,4 +0,0 @@ -1 -1 -ERROR 1064 (42000) at line 3: 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 -ERROR at line 1: USE must be followed by a database name diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 8c98e18aa9b..df0835b830c 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -32,3 +32,10 @@ mysql.time_zone_name OK mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK +create table t1 (a int); +create view v1 as select * from t1; +test.t1 OK +test.t1 OK +drop view v1; +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index ff745021efb..3172a32de76 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1403,92 +1403,6 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; -create database db1; -use db1; -CREATE TABLE t2 ( -a varchar(30) default NULL, -KEY a (a(5)) -); -INSERT INTO t2 VALUES ('alfred'); -INSERT INTO t2 VALUES ('angie'); -INSERT INTO t2 VALUES ('bingo'); -INSERT INTO t2 VALUES ('waffle'); -INSERT INTO t2 VALUES ('lemon'); -create view v2 as select * from t2 where a like 'a%' with check option; - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `t2`; -CREATE TABLE `t2` ( - `a` varchar(30) default NULL, - KEY `a` (`a`(5)) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -LOCK TABLES `t2` WRITE; -/*!40000 ALTER TABLE `t2` DISABLE KEYS */; -INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon'); -/*!40000 ALTER TABLE `t2` ENABLE KEYS */; -UNLOCK TABLES; -DROP TABLE IF EXISTS `v2`; -/*!50001 DROP VIEW IF EXISTS `v2`*/; -/*!50001 CREATE TABLE `v2` ( - `a` varchar(30) -) */; -/*!50001 DROP TABLE IF EXISTS `v2`*/; -/*!50001 DROP VIEW IF EXISTS `v2`*/; -/*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */ -/*!50002 WITH CASCADED CHECK OPTION */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -drop table t2; -drop view v2; -drop database db1; -create database db2; -use db2; -create table t1 (a int); -create table t2 (a int, b varchar(10), primary key(a)); -insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg"); -insert into t1 values (289), (298), (234), (456), (789); -create view v1 as select * from t2; -create view v2 as select * from t1; -drop table t1, t2; -drop view v1, v2; -drop database db2; -create database db1; -use db1; -show tables; -Tables_in_db1 -t1 -t2 -v1 -v2 -select * from t2 order by a; -a b -1 on -2 off -10 pol -12 meg -drop table t1, t2; -drop database db1; ---fields-optionally-enclosed-by=" CREATE DATABASE mysqldump_test_db; USE mysqldump_test_db; CREATE TABLE t1 ( a INT ); @@ -1681,6 +1595,7 @@ select * from t1; a b Osnabrück Köln drop table t1; +--fields-optionally-enclosed-by=" create table `t1` ( t1_name varchar(255) default null, t1_id int(10) unsigned not null auto_increment, @@ -1718,7 +1633,162 @@ t1 CREATE TABLE `t1` ( KEY `t1_name` (`t1_name`) ) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 drop table `t1`; +create table t1(a int); +create table t2(a int); +create table t3(a int); + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t3`; +CREATE TABLE `t3` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +drop table t1, t2, t3; +create table t1 (a int); +mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) +mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 when retrieving data from server + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +drop table t1; End of 4.1 tests +create database db1; +use db1; +CREATE TABLE t2 ( +a varchar(30) default NULL, +KEY a (a(5)) +); +INSERT INTO t2 VALUES ('alfred'); +INSERT INTO t2 VALUES ('angie'); +INSERT INTO t2 VALUES ('bingo'); +INSERT INTO t2 VALUES ('waffle'); +INSERT INTO t2 VALUES ('lemon'); +create view v2 as select * from t2 where a like 'a%' with check option; + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` varchar(30) default NULL, + KEY `a` (`a`(5)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon'); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +DROP TABLE IF EXISTS `v2`; +/*!50001 DROP VIEW IF EXISTS `v2`*/; +/*!50001 CREATE TABLE `v2` ( + `a` varchar(30) +) */; +/*!50001 DROP TABLE IF EXISTS `v2`*/; +/*!50001 DROP VIEW IF EXISTS `v2`*/; +/*!50001 CREATE ALGORITHM=UNDEFINED */ +/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ +/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */ +/*!50002 WITH CASCADED CHECK OPTION */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +drop table t2; +drop view v2; +drop database db1; +use test; +create database db2; +use db2; +create table t1 (a int); +create table t2 (a int, b varchar(10), primary key(a)); +insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg"); +insert into t1 values (289), (298), (234), (456), (789); +create view v1 as select * from t2; +create view v2 as select * from t1; +drop table t1, t2; +drop view v1, v2; +drop database db2; +use test; +create database db1; +use db1; +show tables; +Tables_in_db1 +t1 +t2 +v1 +v2 +select * from t2 order by a; +a b +1 on +2 off +10 pol +12 meg +drop table t1, t2; +drop database db1; +use test; create table t1(a int); create view v1 as select * from t1; @@ -2220,7 +2290,7 @@ RETURN a+b */;; /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; /*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;; /*!50003 SET SESSION SQL_MODE=""*/;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) +/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1 begin set f1= concat( 'hello', f1 ); return f1; @@ -2623,44 +2693,6 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; drop table t1; -create table t1(a int); -create table t2(a int); -create table t3(a int); - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `t3`; -CREATE TABLE `t3` ( - `a` int(11) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( - `a` int(11) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -DROP TABLE IF EXISTS `t2`; -CREATE TABLE `t2` ( - `a` int(11) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -drop table t1, t2, t3; -End of 4.1 tests create table t1 (a int); insert into t1 values (289), (298), (234), (456), (789); create definer = CURRENT_USER view v1 as select * from t1; @@ -2875,3 +2907,54 @@ use mysqldump_dbb; drop view v1; drop table t1; drop database mysqldump_dbb; +use test; +create user mysqltest_1@localhost; +create table t1(a int, b varchar(34)); +reset master; +mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need the RELOAD privilege for this operation (1227) +mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need the RELOAD privilege for this operation (1227) +grant RELOAD on *.* to mysqltest_1@localhost; +mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) +mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) +grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; +CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=537; +CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` varchar(34) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +drop table t1; +drop user mysqltest_1@localhost; +create database mysqldump_myDB; +use mysqldump_myDB; +create user myDB_User; +grant create, create view, select, insert on mysqldump_myDB.* to myDB_User@localhost; +create table t1 (c1 int); +insert into t1 values (3); +use mysqldump_myDB; +create table u1 (f1 int); +insert into u1 values (4); +create view v1 (c1) as select * from t1; +use mysqldump_myDB; +drop view v1; +drop table t1; +drop table u1; +revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; +drop user myDB_User; +drop database mysqldump_myDB; +flush privileges; +use mysqldump_myDB; +select * from mysqldump_myDB.v1; +c1 +3 +select * from mysqldump_myDB.u1; +f1 +4 +use mysqldump_myDB; +drop view v1; +drop table t1; +drop table u1; +revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; +drop user myDB_User; +drop database mysqldump_myDB; +use test; +End of 5.0 tests diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index 942cde83f21..2bf8a58de4e 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -75,3 +75,52 @@ Database: test 2 rows in set. DROP TABLE t1, t2; +Database: information_schema ++---------------------------------------+ +| Tables | ++---------------------------------------+ +| CHARACTER_SETS | +| COLLATIONS | +| COLLATION_CHARACTER_SET_APPLICABILITY | +| COLUMNS | +| COLUMN_PRIVILEGES | +| KEY_COLUMN_USAGE | +| ROUTINES | +| SCHEMATA | +| SCHEMA_PRIVILEGES | +| STATISTICS | +| TABLES | +| TABLE_CONSTRAINTS | +| TABLE_PRIVILEGES | +| TRIGGERS | +| USER_PRIVILEGES | +| VIEWS | ++---------------------------------------+ +Database: INFORMATION_SCHEMA ++---------------------------------------+ +| Tables | ++---------------------------------------+ +| CHARACTER_SETS | +| COLLATIONS | +| COLLATION_CHARACTER_SET_APPLICABILITY | +| COLUMNS | +| COLUMN_PRIVILEGES | +| KEY_COLUMN_USAGE | +| ROUTINES | +| SCHEMATA | +| SCHEMA_PRIVILEGES | +| STATISTICS | +| TABLES | +| TABLE_CONSTRAINTS | +| TABLE_PRIVILEGES | +| TRIGGERS | +| USER_PRIVILEGES | +| VIEWS | ++---------------------------------------+ +Wildcard: inf_rmation_schema ++--------------------+ +| Databases | ++--------------------+ +| information_schema | ++--------------------+ +End of 5.0 tests diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 8055a33ec7d..d9ca863b6bc 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -441,3 +441,9 @@ select-me 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 'insertz error query' at line 1 drop table t1; drop table t1; +sleep; +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 'sleep' at line 1 +sleep; +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 'sleep' at line 1 +; +ERROR 42000: Query was empty diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 09c4f9b29f9..d2111db24fe 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -748,3 +748,4 @@ f1 f2 f3 111111 aaaaaa 1 222222 bbbbbb 2 drop table t1; +Illegal ndb error code: 1186 diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result index 4e5597a4851..aefbcbf6ede 100644 --- a/mysql-test/r/ndb_condition_pushdown.result +++ b/mysql-test/r/ndb_condition_pushdown.result @@ -1307,7 +1307,7 @@ select auto from t1 where ('1901-01-01 01:01:01' between date_time and date_time) order by auto; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort +1 SIMPLE t1 range medium_index medium_index 3 NULL 10 Using where with pushed condition; Using filesort select auto from t1 where ("aaaa" between string and string) and ("aaaa" between vstring and vstring) and @@ -1409,7 +1409,7 @@ select auto from t1 where ('1901-01-01 01:01:01' not between date_time and date_time) order by auto; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort +1 SIMPLE t1 range medium_index medium_index 3 NULL 20 Using where with pushed condition; Using filesort select auto from t1 where ("aaaa" not between string and string) and ("aaaa" not between vstring and vstring) and diff --git a/mysql-test/r/ndb_lock.result b/mysql-test/r/ndb_lock.result index 3b433023843..2c212b9cfef 100644 --- a/mysql-test/r/ndb_lock.result +++ b/mysql-test/r/ndb_lock.result @@ -64,17 +64,26 @@ pk u o insert into t1 values (1,1,1); drop table t1; create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb; -insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3); +insert into t1 values (1,'one',1); begin; select * from t1 where x = 1 for update; x y z 1 one 1 begin; -select * from t1 where x = 2 for update; +select * from t1 where x = 1 for update; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +rollback; +rollback; +insert into t1 values (2,'two',2),(3,"three",3); +begin; +select * from t1 where x = 1 for update; x y z -2 two 2 +1 one 1 select * from t1 where x = 1 for update; ERROR HY000: Lock wait timeout exceeded; try restarting transaction +select * from t1 where x = 2 for update; +x y z +2 two 2 rollback; commit; begin; diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 18eb10f0673..daedfa50b80 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -97,39 +97,39 @@ Warnings: Warning 1265 Data truncated for column 'd' at row 1 UPDATE t1 SET d=NULL; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'd' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 1 INSERT INTO t1 (a) values (null); ERROR 23000: Column 'a' cannot be null INSERT INTO t1 (a) values (1/null); ERROR 23000: Column 'a' cannot be null INSERT INTO t1 (a) values (null),(null); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2 INSERT INTO t1 (b) values (null); ERROR 23000: Column 'b' cannot be null INSERT INTO t1 (b) values (1/null); ERROR 23000: Column 'b' cannot be null INSERT INTO t1 (b) values (null),(null); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'b' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'b' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2 INSERT INTO t1 (c) values (null); ERROR 23000: Column 'c' cannot be null INSERT INTO t1 (c) values (1/null); ERROR 23000: Column 'c' cannot be null INSERT INTO t1 (c) values (null),(null); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'c' at row 2 INSERT INTO t1 (d) values (null); ERROR 23000: Column 'd' cannot be null INSERT INTO t1 (d) values (1/null); ERROR 23000: Column 'd' cannot be null INSERT INTO t1 (d) values (null),(null); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'd' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'd' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'd' at row 2 select * from t1; a b c d 0 0000-00-00 00:00:00 0 diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 7f746a3dbd8..6eb3cf312a0 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -342,7 +342,7 @@ index (id2) ); insert into t1 values(null,null),(1,1); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'id2' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'id2' at row 1 select * from t1; id id2 NULL 0 diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 1fcfb11525e..8f9fd50eced 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -3,9 +3,12 @@ create table t1(f1 int); insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/emailAddress=abstract.mysql.developer@mysql.com"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; +connect(localhost,ssl_user5,,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'ssl_user5'@'localhost' (using password: NO) SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA @@ -39,7 +42,7 @@ f1 delete from t1; ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1' drop user ssl_user1@localhost, ssl_user2@localhost, -ssl_user3@localhost, ssl_user4@localhost; +ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; mysqltest: Could not open connection 'default': 2026 SSL connection error mysqltest: Could not open connection 'default': 2026 SSL connection error diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index a36935a583d..64653de5e9c 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -280,6 +280,8 @@ info text NOT NULL default '', ipnr varchar(30) NOT NULL default '', PRIMARY KEY (member_id) ) ENGINE=MyISAM PACK_KEYS=1; +Warnings: +Warning 1101 BLOB/TEXT column 'info' can't have a default value insert into t1 (member_id) values (1),(2),(3); select member_id, nickname, voornaam FROM t1 ORDER by lastchange_datum DESC LIMIT 2; @@ -852,3 +854,40 @@ b a 20 1 10 2 DROP TABLE t1; +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); +explain SELECT t1.b as a, t2.b as c FROM +t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +SELECT t2.b as c FROM +t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +c +NULL +NULL +2 +explain SELECT t1.b as a, t2.b as c FROM +t1 JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * from t1; +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 SELECT * from t1; +CREATE TABLE t4 LIKE t1; +INSERT INTO t4 SELECT * from t1; +INSERT INTO t1 values (0,0),(4,4); +SELECT t2.b FROM t1 LEFT JOIN (t2, t3 LEFT JOIN t4 ON t3.a=t4.a) +ON (t1.a=t2.a AND t1.b=t3.b) order by t2.b; +b +NULL +NULL +1 +2 +3 +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/r/perror.result b/mysql-test/r/perror.result new file mode 100644 index 00000000000..4946523bc42 --- /dev/null +++ b/mysql-test/r/perror.result @@ -0,0 +1 @@ +Illegal error code: 10000 diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 3d352a02ad2..080187cfa7b 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -516,77 +516,6 @@ SELECT FOUND_ROWS(); FOUND_ROWS() 2 deallocate prepare stmt; -create table t1 (a char(3) not null, b char(3) not null, -c char(3) not null, primary key (a, b, c)); -create table t2 like t1; -prepare stmt from -"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) - where t1.a=1"; -execute stmt; -a -execute stmt; -a -execute stmt; -a -prepare stmt from -"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from -(t1 left outer join t2 on t2.a=? and t1.b=t2.b) -left outer join t2 t3 on t3.a=? where t1.a=?"; -set @a:=1, @b:=1, @c:=1; -execute stmt using @a, @b, @c; -a b c a b c -execute stmt using @a, @b, @c; -a b c a b c -execute stmt using @a, @b, @c; -a b c a b c -deallocate prepare stmt; -drop table t1,t2; -SET @aux= "SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS A, - INFORMATION_SCHEMA.COLUMNS B - WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA - AND A.TABLE_NAME = B.TABLE_NAME - AND A.COLUMN_NAME = B.COLUMN_NAME AND - A.TABLE_NAME = 'user'"; -prepare my_stmt from @aux; -execute my_stmt; -COUNT(*) -37 -execute my_stmt; -COUNT(*) -37 -execute my_stmt; -COUNT(*) -37 -deallocate prepare my_stmt; -drop procedure if exists p1| -drop table if exists t1| -create table t1 (id int)| -insert into t1 values(1)| -create procedure p1(a int, b int) -begin -declare c int; -select max(id)+1 into c from t1; -insert into t1 select a+b; -insert into t1 select a-b; -insert into t1 select a-c; -end| -set @a= 3, @b= 4| -prepare stmt from "call p1(?, ?)"| -execute stmt using @a, @b| -execute stmt using @a, @b| -select * from t1| -id -1 -7 --1 -1 -7 --1 --5 -deallocate prepare stmt| -drop procedure p1| -drop table t1| drop table if exists t1; Warnings: Note 1051 Unknown table 't1' @@ -650,47 +579,6 @@ id 3 deallocate prepare stmt; drop table t1, t2; -create table t1 (a int); -insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -prepare stmt from "select * from t1 limit ?, ?"; -set @offset=0, @limit=1; -execute stmt using @offset, @limit; -a -1 -select * from t1 limit 0, 1; -a -1 -set @offset=3, @limit=2; -execute stmt using @offset, @limit; -a -4 -5 -select * from t1 limit 3, 2; -a -4 -5 -prepare stmt from "select * from t1 limit ?"; -execute stmt using @limit; -a -1 -2 -prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; -ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' -prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; -set @offset=9; -set @limit=2; -execute stmt using @offset, @limit; -a -10 -1 -prepare stmt from "(select * from t1 limit ?, ?) union all - (select * from t1 limit ?, ?) order by a limit ?"; -execute stmt using @offset, @limit, @offset, @limit, @limit; -a -10 -10 -drop table t1; -deallocate prepare stmt; create table t1 (id int); prepare stmt from "insert into t1 (id) select id from t1 union select id from t1"; execute stmt; @@ -791,15 +679,6 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp select ? from t1; 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 '? from t1' at line 1 drop table t1; -CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; -CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; -CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; -PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; -EXECUTE b12651; -1 -DROP VIEW b12651_V1; -DROP TABLE b12651_T1, b12651_T2; -DEALLOCATE PREPARE b12651; prepare stmt from "select @@time_zone"; execute stmt; @@time_zone @@ -1016,6 +895,147 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count; @@max_prepared_stmt_count @@prepared_stmt_count 3 0 set global max_prepared_stmt_count= @old_max_prepared_stmt_count; +drop table if exists t1; +create temporary table if not exists t1 (a1 int); +prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1"; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +deallocate prepare stmt; +End of 4.1 tests +create table t1 (a varchar(20)); +insert into t1 values ('foo'); +prepare stmt FROM 'SELECT char_length (a) FROM t1'; +ERROR 42000: FUNCTION test.char_length does not exist +drop table t1; +create table t1 (a char(3) not null, b char(3) not null, +c char(3) not null, primary key (a, b, c)); +create table t2 like t1; +prepare stmt from +"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) + where t1.a=1"; +execute stmt; +a +execute stmt; +a +execute stmt; +a +prepare stmt from +"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from +(t1 left outer join t2 on t2.a=? and t1.b=t2.b) +left outer join t2 t3 on t3.a=? where t1.a=?"; +set @a:=1, @b:=1, @c:=1; +execute stmt using @a, @b, @c; +a b c a b c +execute stmt using @a, @b, @c; +a b c a b c +execute stmt using @a, @b, @c; +a b c a b c +deallocate prepare stmt; +drop table t1,t2; +SET @aux= "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS A, + INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME + AND A.COLUMN_NAME = B.COLUMN_NAME AND + A.TABLE_NAME = 'user'"; +prepare my_stmt from @aux; +execute my_stmt; +COUNT(*) +37 +execute my_stmt; +COUNT(*) +37 +execute my_stmt; +COUNT(*) +37 +deallocate prepare my_stmt; +drop procedure if exists p1| +drop table if exists t1| +create table t1 (id int)| +insert into t1 values(1)| +create procedure p1(a int, b int) +begin +declare c int; +select max(id)+1 into c from t1; +insert into t1 select a+b; +insert into t1 select a-b; +insert into t1 select a-c; +end| +set @a= 3, @b= 4| +prepare stmt from "call p1(?, ?)"| +execute stmt using @a, @b| +execute stmt using @a, @b| +select * from t1| +id +1 +7 +-1 +1 +7 +-1 +-5 +deallocate prepare stmt| +drop procedure p1| +drop table t1| +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +prepare stmt from "select * from t1 limit ?, ?"; +set @offset=0, @limit=1; +execute stmt using @offset, @limit; +a +1 +select * from t1 limit 0, 1; +a +1 +set @offset=3, @limit=2; +execute stmt using @offset, @limit; +a +4 +5 +select * from t1 limit 3, 2; +a +4 +5 +prepare stmt from "select * from t1 limit ?"; +execute stmt using @limit; +a +1 +2 +prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; +ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' +prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; +set @offset=9; +set @limit=2; +execute stmt using @offset, @limit; +a +10 +1 +prepare stmt from "(select * from t1 limit ?, ?) union all + (select * from t1 limit ?, ?) order by a limit ?"; +execute stmt using @offset, @limit, @offset, @limit, @limit; +a +10 +10 +drop table t1; +deallocate prepare stmt; +CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; +CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; +CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; +PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; +EXECUTE b12651; +1 +DROP VIEW b12651_V1; +DROP TABLE b12651_T1, b12651_T2; +DEALLOCATE PREPARE b12651; create table t1 (id int); prepare ins_call from "insert into t1 (id) values (1)"; execute ins_call; @@ -1277,3 +1297,18 @@ ERROR 3D000: No database selected create temporary table t1 (i int); ERROR 3D000: No database selected use test; +DROP TABLE IF EXISTS t1, t2, t3; +CREATE TABLE t1 (i BIGINT, j BIGINT); +CREATE TABLE t2 (i BIGINT); +CREATE TABLE t3 (i BIGINT, j BIGINT); +PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i) + LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j)) + WHERE t1.i = ?"; +SET @a= 1; +EXECUTE stmt USING @a; +i j i i j +EXECUTE stmt USING @a; +i j i i j +DEALLOCATE PREPARE stmt; +DROP TABLE IF EXISTS t1, t2, t3; +End of 5.0 tests. diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index 3c736a508d3..ac8ae6def9f 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -298,7 +298,7 @@ t9 MyISAM 10 Dynamic 2 216 432 # 2048 0 NULL # # # latin1_swedish_ci NULL prepare stmt4 from ' show status like ''Threads_running'' '; execute stmt4; Variable_name Value -Threads_running 1 +Threads_running # prepare stmt4 from ' show variables like ''sql_mode'' '; execute stmt4; Variable_name Value diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index aa355067d1f..205c084b71f 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -1304,7 +1304,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index ea7ed9371e8..2e7c4785542 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -1287,7 +1287,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index fe4de89d6c7..8a0da364598 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -1288,7 +1288,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index bee7b2400b8..1c6e11f203c 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -1330,7 +1330,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two @@ -4344,7 +4344,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index d352ec9f9e2..3546b05870a 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -1287,7 +1287,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 8ce4c624fbc..b1986ca62dc 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -1287,7 +1287,7 @@ set @arg00=NULL; set @arg01=2; execute stmt1 using @arg00, @arg01; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 select a,b from t1 order by a; a b 0 two diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 926a980f9c4..a735b52a26f 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -947,18 +947,24 @@ COUNT(*) Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1 +Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid' +Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid' SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid'; COUNT(*) 0 Warnings: Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1 +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' +Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid' show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index a1f03a292c5..3edf56496fe 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -838,3 +838,106 @@ select a, hex(filler) from t1 where a not between 'b' and 'b'; a hex(filler) a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 drop table t1,t2,t3; +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, key(a)); +insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C; +set @a="select * from t2 force index (a) where a NOT IN(0"; +select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z; +count(*) +1000 +set @a=concat(@a, ')'); +insert into t2 values (11),(13),(15); +set @b= concat("explain ", @a); +prepare stmt1 from @b; +execute stmt1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index a a 5 NULL 1003 Using where; Using index +prepare stmt1 from @a; +execute stmt1; +a +11 +13 +15 +drop table t1, t2; +CREATE TABLE t1 ( +id int NOT NULL DEFAULT '0', +b int NOT NULL DEFAULT '0', +c int NOT NULL DEFAULT '0', +INDEX idx1(b,c), INDEX idx2(c)); +INSERT INTO t1(id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); +INSERT INTO t1(b,c) VALUES (3,4), (3,4); +SELECT * FROM t1 WHERE b<=3 AND 3<=c; +id b c +0 3 4 +0 3 4 +SELECT * FROM t1 WHERE 3 BETWEEN b AND c; +id b c +0 3 4 +0 3 4 +EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where +EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where +SELECT * FROM t1 WHERE 0 < b OR 0 > c; +id b c +0 3 4 +0 3 4 +SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; +id b c +0 3 4 +0 3 4 +EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where +EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where +DROP TABLE t1; +CREATE TABLE t1 ( +item char(20) NOT NULL default '', +started datetime NOT NULL default '0000-00-00 00:00:00', +price decimal(16,3) NOT NULL default '0.000', +PRIMARY KEY (item,started) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES +('A1','2005-11-01 08:00:00',1000), +('A1','2005-11-15 00:00:00',2000), +('A1','2005-12-12 08:00:00',3000), +('A2','2005-12-01 08:00:00',1000); +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +DROP INDEX `PRIMARY` ON t1; +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +Warnings: +Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1 +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; +item started price +A1 2005-11-01 08:00:00 1000.000 +A1 2005-11-15 00:00:00 2000.000 +DROP TABLE t1; diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index d8fa4dbbb72..9b07281aa7b 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -41,3 +41,14 @@ Table Op Msg_type Msg_text test.t1 repair warning Number of rows changed from 0 to 1 test.t1 repair status OK drop table t1; +CREATE TABLE t1(a INT, KEY(a)); +INSERT INTO t1 VALUES(1),(2),(3),(4),(5); +SET myisam_repair_threads=2; +REPAIR TABLE t1; +Table Op Msg_type Msg_text +test.t1 repair status OK +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 1 a 1 a A 5 NULL NULL YES BTREE +SET myisam_repair_threads=@@global.myisam_repair_threads; +DROP TABLE t1; diff --git a/mysql-test/r/rpl_ndb_innodb_trans.result b/mysql-test/r/rpl_ndb_innodb_trans.result new file mode 100644 index 00000000000..148e6247b03 --- /dev/null +++ b/mysql-test/r/rpl_ndb_innodb_trans.result @@ -0,0 +1,103 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +create table t1 (a int, unique(a)) engine=ndbcluster; +create table t2 (a int, unique(a)) engine=innodb; +begin; +insert into t1 values(1); +insert into t2 values(1); +rollback; +select count(*) from t1; +count(*) +0 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +0 +select count(*) from t2; +count(*) +0 +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +delete from t1; +delete from t2; +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +2 +select count(*) from t2; +count(*) +0 +delete from t1; +delete from t2; +begin; +insert into t2 values(3),(4); +insert into t1 values(3),(4); +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +Warnings: +Warning 1262 Row 1 was truncated; it contained more data than there were input columns +Warning 1262 Row 2 was truncated; it contained more data than there were input columns +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +4 +select count(*) from t2; +count(*) +0 +select count(*) from t1; +count(*) +4 +select count(*) from t2; +count(*) +0 +drop table t1,t2; diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 5dfda16c763..7b096b27733 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -420,4 +420,48 @@ SELECT * FROM t1; col test DROP PROCEDURE p1; + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating procedure... +/*!50003 CREATE PROCEDURE p1() SET @a = 1 */; +/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */; + +---> Checking on master... +SHOW CREATE PROCEDURE p1; +Procedure sql_mode Create Procedure +p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() +SET @a = 1 +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function +f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) +RETURN 0 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SHOW CREATE PROCEDURE p1; +Procedure sql_mode Create Procedure +p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() +SET @a = 1 +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function +f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) +RETURN 0 + +---> connection: master + +---> Cleaning up... +DROP PROCEDURE p1; +DROP FUNCTION f1; drop table t1; diff --git a/mysql-test/r/rpl_trigger.result b/mysql-test/r/rpl_trigger.result index 3e4a3349e13..49f0f5c4c44 100644 --- a/mysql-test/r/rpl_trigger.result +++ b/mysql-test/r/rpl_trigger.result @@ -896,3 +896,50 @@ Tables_in_test (t_) SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer RESET MASTER; +START SLAVE; + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating objects... +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); +/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 +FOR EACH ROW +INSERT INTO t2 VALUES(NEW.c * 10) */; + +---> Inserting value... +INSERT INTO t1 VALUES(1); + +---> Checking on master... +SELECT * FROM t1; +c +1 +SELECT * FROM t2; +c +10 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SELECT * FROM t1; +c +1 +SELECT * FROM t2; +c +10 + +---> connection: master + +---> Cleaning up... +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_view.result index cf4c161b296..5a101defe38 100644 --- a/mysql-test/r/rpl_view.result +++ b/mysql-test/r/rpl_view.result @@ -54,3 +54,40 @@ slave-bin.000001 # Query 1 # use `test`; delete from v1 where a=2 slave-bin.000001 # Query 1 # use `test`; ALTER ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW v1 AS select a as b from t1 slave-bin.000001 # Query 1 # use `test`; drop view v1 slave-bin.000001 # Query 1 # use `test`; drop table t1 + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating objects... +CREATE TABLE t1(c INT); +/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */; + +---> Inserting value... +INSERT INTO t1 VALUES(1); + +---> Checking on master... +SELECT * FROM t1; +c +1 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SELECT * FROM t1; +c +1 + +---> connection: master + +---> Cleaning up... +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index c2218585f7c..0c62d3f570f 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2328,9 +2328,9 @@ explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 left join t4 on id3 = id4 where id2 = 1 or id4 = 1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found +1 SIMPLE t4 const id4 NULL NULL NULL 1 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 -1 SIMPLE t2 ALL NULL NULL NULL NULL 1 -1 SIMPLE t4 ALL id4 NULL NULL NULL 1 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 left join t4 on id3 = id4 where id2 = 1 or id4 = 1; id1 id2 id3 id4 id44 @@ -2736,6 +2736,81 @@ SELECT i='1e+01',i=1e+01, i in (1e+01,1e+01), i in ('1e+01','1e+01') FROM t1; i='1e+01' i=1e+01 i in (1e+01,1e+01) i in ('1e+01','1e+01') 0 1 1 1 DROP TABLE t1; +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,1), (2,1), (4,10); +CREATE TABLE t2 (a int PRIMARY KEY, b int, KEY b (b)); +INSERT INTO t2 VALUES (1,NULL), (2,10); +ALTER TABLE t1 ENABLE KEYS; +EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index b b 5 NULL 2 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where +SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +a b a b +1 NULL 1 1 +1 NULL 2 1 +1 NULL 4 10 +2 10 4 10 +EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index b b 5 NULL 2 Using index +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where +SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +a b a b +1 NULL 1 1 +1 NULL 2 1 +1 NULL 4 10 +2 10 4 10 +DROP TABLE IF EXISTS t1,t2; +CREATE TABLE t1 (key1 float default NULL, UNIQUE KEY key1 (key1)); +CREATE TABLE t2 (key2 float default NULL, UNIQUE KEY key2 (key2)); +INSERT INTO t1 VALUES (0.3762),(0.3845),(0.6158),(0.7941); +INSERT INTO t2 VALUES (1.3762),(1.3845),(1.6158),(1.7941); +explain select max(key1) from t1 where key1 <= 0.6158; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select max(key2) from t2 where key2 <= 1.6158; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select min(key1) from t1 where key1 >= 0.3762; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select min(key2) from t2 where key2 >= 1.3762; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select max(key1), min(key2) from t1, t2 +where key1 <= 0.6158 and key2 >= 1.3762; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +select max(key1) from t1 where key1 <= 0.6158; +max(key1) +0.61580002307892 +select max(key2) from t2 where key2 <= 1.6158; +max(key2) +1.6158000230789 +select min(key1) from t1 where key1 >= 0.3762; +min(key1) +0.37619999051094 +select min(key2) from t2 where key2 >= 1.3762; +min(key2) +1.3761999607086 +select max(key1), min(key2) from t1, t2 +where key1 <= 0.6158 and key2 >= 1.3762; +max(key1) min(key2) +0.61580002307892 1.3761999607086 +select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; +max(key1) +0.61580002307892 +select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; +min(key1) +0.37619999051094 +DROP TABLE t1,t2; CREATE TABLE t1 ( K2C4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '', K4N4 varchar(4) character set latin1 collate latin1_bin NOT NULL default '0000', @@ -3404,3 +3479,41 @@ Warning 1466 Leading spaces are removed from name ' a ' execute stmt; a 1 +CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); +CREATE TABLE t2 (c int NOT NULL, INDEX idx(c)); +INSERT INTO t2 VALUES +(1), (1), (1), (1), (1), (1), (1), (1), +(2), (2), (2), (2), +(3), (3), +(4); +EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 ref idx idx 4 const 7 Using index +EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 ref idx idx 4 const 1 Using index +DROP TABLE t1, t2; +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int); +INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2); +CREATE TABLE t2 (b int, c INT, INDEX idx1(b)); +INSERT INTO t2 VALUES (2,1), (3,2); +CREATE TABLE t3 (d int, e int, INDEX idx1(d)); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50); +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id +WHERE t1.id=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 const idx1 NULL NULL NULL 1 +1 SIMPLE t3 ref idx1 idx1 5 const 3 Using where +SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id +WHERE t1.id=2; +id a b c d e +2 NULL NULL NULL 2 10 +2 NULL NULL NULL 2 20 +2 NULL NULL NULL 2 40 +2 NULL NULL NULL 2 50 +DROP TABLE t1,t2,t3; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 994501767ba..7bdfa78066c 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -625,3 +625,7 @@ View Create View v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1` DROP PROCEDURE p1; DROP VIEW v1; +SHOW TABLES FROM no_such_database; +ERROR 42000: Unknown database 'no_such_database' +SHOW COLUMNS FROM no_such_table; +ERROR 42S02: Table 'test.no_such_table' doesn't exist diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result index 8bdb9a724d7..4ae38861d29 100644 --- a/mysql-test/r/sp-code.result +++ b/mysql-test/r/sp-code.result @@ -155,11 +155,11 @@ Pos Instruction 0 stmt 9 "drop temporary table if exists sudoku..." 1 stmt 1 "create temporary table sudoku_work ( ..." 2 stmt 1 "create temporary table sudoku_schedul..." -3 stmt 95 "call sudoku_init(" +3 stmt 95 "call sudoku_init()" 4 jump_if_not 7(8) p_naive@0 5 stmt 4 "update sudoku_work set cnt = 0 where ..." 6 jump 8 -7 stmt 95 "call sudoku_count(" +7 stmt 95 "call sudoku_count()" 8 stmt 6 "insert into sudoku_schedule (row,col)..." 9 set v_scounter@2 0 10 set v_i@3 1 @@ -199,3 +199,10 @@ Pos Instruction 44 jump 14 45 stmt 9 "drop temporary table sudoku_work, sud..." drop procedure sudoku_solve; +DROP PROCEDURE IF EXISTS p1; +CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1); +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 2 "CREATE INDEX idx ON t1 (c1)" +DROP PROCEDURE p1; +End of 5.0 tests. diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 924963017eb..85ea624ce2f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -634,6 +634,45 @@ flush tables; return 5; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin reset query cache; +return 1; end| +ERROR 0A000: RESET is not allowed in stored function or trigger +create function bug8409() returns int begin reset master; +return 1; end| +ERROR 0A000: RESET is not allowed in stored function or trigger +create function bug8409() returns int begin reset slave; +return 1; end| +ERROR 0A000: RESET is not allowed in stored function or trigger +create function bug8409() returns int begin flush hosts; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush privileges; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush tables with read lock; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush tables; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush logs; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush status; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush slave; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush master; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush des_key_file; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function bug8409() returns int begin flush user_resources; +return 1; end| +ERROR 0A000: FLUSH is not allowed in stored function or trigger create procedure bug9529_901234567890123456789012345678901234567890123456789012345() begin end| @@ -1174,3 +1213,16 @@ drop procedure bug15091; drop function if exists bug16896; create aggregate function bug16896() returns int return 1; ERROR 42000: AGGREGATE is not supported for stored functions +DROP PROCEDURE IF EXISTS bug14702; +CREATE IF NOT EXISTS PROCEDURE bug14702() +BEGIN +END; +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 'IF NOT EXISTS PROCEDURE bug14702() +BEGIN +END' at line 1 +CREATE PROCEDURE IF NOT EXISTS bug14702() +BEGIN +END; +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 'IF NOT EXISTS bug14702() +BEGIN +END' at line 1 diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result index a53b4c4d246..1198efc4f3b 100644 --- a/mysql-test/r/sp-security.result +++ b/mysql-test/r/sp-security.result @@ -451,3 +451,55 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857'; Host User Password localhost user19857 *82DC221D557298F6CE9961037DB1C90604792F5C DROP USER user19857@localhost; +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f_suid; +DROP PROCEDURE IF EXISTS p_suid; +DROP FUNCTION IF EXISTS f_evil; +DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%'; +FLUSH PRIVILEGES; +CREATE TABLE t1 (i INT); +CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0; +CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0; +CREATE USER mysqltest_u1@localhost; +GRANT EXECUTE ON test.* TO mysqltest_u1@localhost; +CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT +SQL SECURITY INVOKER +BEGIN +SET @a:= CURRENT_USER(); +SET @b:= (SELECT COUNT(*) FROM t1); +RETURN @b; +END| +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil(); +SELECT COUNT(*) FROM t1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT f_evil(); +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +SELECT f_suid(f_evil()); +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +CALL p_suid(f_evil()); +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +SELECT * FROM v1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +DROP VIEW v1; +DROP FUNCTION f_evil; +DROP USER mysqltest_u1@localhost; +DROP PROCEDURE p_suid; +DROP FUNCTION f_suid; +DROP TABLE t1; +End of 5.0 tests. diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 7807b7b52ce..854935b071b 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -4872,8 +4872,6 @@ declare continue handler for sqlexception begin end; select no_such_function(); end| call bug18787()| -no_such_function() -NULL drop procedure bug18787| create database bug18344_012345678901| use bug18344_012345678901| @@ -5057,6 +5055,310 @@ concat('data was: /', var1, '/') data was: /1/ drop table t3| drop procedure bug15217| +DROP PROCEDURE IF EXISTS bug21013 | +CREATE PROCEDURE bug21013(IN lim INT) +BEGIN +DECLARE i INT DEFAULT 0; +WHILE (i < lim) DO +SET @b = LOCATE(_latin1'b', @a, 1); +SET i = i + 1; +END WHILE; +END | +SET @a = _latin2"aaaaaaaaaa" | +CALL bug21013(10) | +DROP PROCEDURE bug21013 | +DROP DATABASE IF EXISTS mysqltest1| +DROP DATABASE IF EXISTS mysqltest2| +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| +CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8| +use mysqltest1| +CREATE FUNCTION bug16211_f1() RETURNS CHAR(10) +RETURN ""| +CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r +RETURN ""| +CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10) +RETURN ""| +CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r +RETURN ""| +SHOW CREATE FUNCTION bug16211_f1| +Function sql_mode Create Function +bug16211_f1 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION bug16211_f2| +Function sql_mode Create Function +bug16211_f2 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +Function sql_mode Create Function +bug16211_f3 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| +Function sql_mode Create Function +bug16211_f4 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r +RETURN "" +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| +dtd_identifier +char(10) CHARSET koi8r +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| +dtd_identifier +char(10) CHARSET koi8r +SELECT CHARSET(bug16211_f1())| +CHARSET(bug16211_f1()) +utf8 +SELECT CHARSET(bug16211_f2())| +CHARSET(bug16211_f2()) +koi8r +SELECT CHARSET(mysqltest2.bug16211_f3())| +CHARSET(mysqltest2.bug16211_f3()) +utf8 +SELECT CHARSET(mysqltest2.bug16211_f4())| +CHARSET(mysqltest2.bug16211_f4()) +koi8r +ALTER DATABASE mysqltest1 CHARACTER SET cp1251| +ALTER DATABASE mysqltest2 CHARACTER SET cp1251| +SHOW CREATE FUNCTION bug16211_f1| +Function sql_mode Create Function +bug16211_f1 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION bug16211_f2| +Function sql_mode Create Function +bug16211_f2 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +Function sql_mode Create Function +bug16211_f3 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| +Function sql_mode Create Function +bug16211_f4 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r +RETURN "" +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| +dtd_identifier +char(10) CHARSET koi8r +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| +dtd_identifier +char(10) CHARSET koi8r +SELECT CHARSET(bug16211_f1())| +CHARSET(bug16211_f1()) +utf8 +SELECT CHARSET(bug16211_f2())| +CHARSET(bug16211_f2()) +koi8r +SELECT CHARSET(mysqltest2.bug16211_f3())| +CHARSET(mysqltest2.bug16211_f3()) +utf8 +SELECT CHARSET(mysqltest2.bug16211_f4())| +CHARSET(mysqltest2.bug16211_f4()) +koi8r +use test| +DROP DATABASE mysqltest1| +DROP DATABASE mysqltest2| +DROP DATABASE IF EXISTS mysqltest1| +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| +use mysqltest1| +CREATE PROCEDURE bug16676_p1( +IN p1 CHAR(10), +INOUT p2 CHAR(10), +OUT p3 CHAR(10)) +BEGIN +SELECT CHARSET(p1), COLLATION(p1); +SELECT CHARSET(p2), COLLATION(p2); +SELECT CHARSET(p3), COLLATION(p3); +END| +CREATE PROCEDURE bug16676_p2( +IN p1 CHAR(10) CHARSET koi8r, +INOUT p2 CHAR(10) CHARSET cp1251, +OUT p3 CHAR(10) CHARSET greek) +BEGIN +SELECT CHARSET(p1), COLLATION(p1); +SELECT CHARSET(p2), COLLATION(p2); +SELECT CHARSET(p3), COLLATION(p3); +END| +SET @v2 = 'b'| +SET @v3 = 'c'| +CALL bug16676_p1('a', @v2, @v3)| +CHARSET(p1) COLLATION(p1) +utf8 utf8_general_ci +CHARSET(p2) COLLATION(p2) +utf8 utf8_general_ci +CHARSET(p3) COLLATION(p3) +utf8 utf8_general_ci +CALL bug16676_p2('a', @v2, @v3)| +CHARSET(p1) COLLATION(p1) +koi8r koi8r_general_ci +CHARSET(p2) COLLATION(p2) +cp1251 cp1251_general_ci +CHARSET(p3) COLLATION(p3) +greek greek_general_ci +use test| +DROP DATABASE mysqltest1| +drop table if exists t3| +drop table if exists t4| +drop procedure if exists bug8153_subselect| +drop procedure if exists bug8153_subselect_a| +drop procedure if exists bug8153_subselect_b| +drop procedure if exists bug8153_proc_a| +drop procedure if exists bug8153_proc_b| +create table t3 (a int)| +create table t4 (a int)| +insert into t3 values (1), (1), (2), (3)| +insert into t4 values (1), (1)| +create procedure bug8153_subselect() +begin +declare continue handler for sqlexception +begin +select 'statement failed'; +end; +update t3 set a=a+1 where (select a from t4 where a=1) is null; +select 'statement after update'; +end| +call bug8153_subselect()| +statement failed +statement failed +statement after update +statement after update +select * from t3| +a +1 +1 +2 +3 +call bug8153_subselect()| +statement failed +statement failed +statement after update +statement after update +select * from t3| +a +1 +1 +2 +3 +drop procedure bug8153_subselect| +create procedure bug8153_subselect_a() +begin +declare continue handler for sqlexception +begin +select 'in continue handler'; +end; +select 'reachable code a1'; +call bug8153_subselect_b(); +select 'reachable code a2'; +end| +create procedure bug8153_subselect_b() +begin +select 'reachable code b1'; +update t3 set a=a+1 where (select a from t4 where a=1) is null; +select 'unreachable code b2'; +end| +call bug8153_subselect_a()| +reachable code a1 +reachable code a1 +reachable code b1 +reachable code b1 +in continue handler +in continue handler +reachable code a2 +reachable code a2 +select * from t3| +a +1 +1 +2 +3 +call bug8153_subselect_a()| +reachable code a1 +reachable code a1 +reachable code b1 +reachable code b1 +in continue handler +in continue handler +reachable code a2 +reachable code a2 +select * from t3| +a +1 +1 +2 +3 +drop procedure bug8153_subselect_a| +drop procedure bug8153_subselect_b| +create procedure bug8153_proc_a() +begin +declare continue handler for sqlexception +begin +select 'in continue handler'; +end; +select 'reachable code a1'; +call bug8153_proc_b(); +select 'reachable code a2'; +end| +create procedure bug8153_proc_b() +begin +select 'reachable code b1'; +select no_such_function(); +select 'unreachable code b2'; +end| +call bug8153_proc_a()| +reachable code a1 +reachable code a1 +reachable code b1 +reachable code b1 +in continue handler +in continue handler +reachable code a2 +reachable code a2 +drop procedure bug8153_proc_a| +drop procedure bug8153_proc_b| +drop table t3| +drop table t4| +drop procedure if exists bug19862| +CREATE TABLE t11 (a INT)| +CREATE TABLE t12 (a INT)| +CREATE FUNCTION bug19862(x INT) RETURNS INT +BEGIN +INSERT INTO t11 VALUES (x); +RETURN x+1; +END| +INSERT INTO t12 VALUES (1), (2)| +SELECT bug19862(a) FROM t12 ORDER BY 1| +bug19862(a) +2 +3 +SELECT * FROM t11| +a +1 +2 +DROP TABLE t11, t12| +DROP FUNCTION bug19862| drop table if exists t3| drop database if exists mysqltest1| create table t3 (a int)| @@ -5072,4 +5374,24 @@ a 1 use test| drop table t3| +DROP PROCEDURE IF EXISTS bug16899_p1| +DROP FUNCTION IF EXISTS bug16899_f1| +CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1() +BEGIN +SET @a = 1; +END| +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY +FUNCTION bug16899_f1() RETURNS INT +BEGIN +RETURN 1; +END| +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +drop procedure if exists bug21416| +create procedure bug21416() show create procedure bug21416| +call bug21416()| +Procedure sql_mode Create Procedure +bug21416 CREATE DEFINER=`root`@`localhost` PROCEDURE `bug21416`() +show create procedure bug21416 +drop procedure bug21416| drop table t1,t2; diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index d0cf11d0511..e144eed92f5 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -5,7 +5,9 @@ select @@sql_mode; REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER DROP TABLE IF EXISTS t1; CREATE TABLE t1 (col1 date); -INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29'); +INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29'); +INSERT INTO t1 VALUES('0000-10-31'); +ERROR 22007: Incorrect date value: '0000-10-31' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-0-31'); ERROR 22007: Incorrect date value: '2004-0-31' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-01-02'),('2004-0-31'); @@ -54,7 +56,6 @@ Warning 1265 Data truncated for column 'col1' at row 3 select * from t1; col1 2004-01-01 -0000-10-31 2004-02-29 2004-01-02 2004-01-03 @@ -121,7 +122,9 @@ col1 drop table t1; set @@sql_mode='ansi,traditional'; CREATE TABLE t1 (col1 datetime); -INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00'); +INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00'); +INSERT INTO t1 VALUES('0000-10-31 15:30:00'); +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-0-31 15:30:00'); ERROR 22007: Incorrect datetime value: '2004-0-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-10-0 15:30:00'); @@ -141,7 +144,6 @@ ERROR 22007: Incorrect datetime value: '59' for column 'col1' at row 1 select * from t1; col1 2004-10-31 15:30:00 -0000-10-31 15:30:00 2004-02-29 15:30:00 drop table t1; CREATE TABLE t1 (col1 timestamp); @@ -204,6 +206,7 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); +ERROR 22007: Incorrect date value: '0000-10-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect date value: '2004-00-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -219,6 +222,7 @@ ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_ti INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -255,6 +259,7 @@ INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE)); INSERT INTO t1 (col2) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31' INSERT INTO t1 (col1) VALUES(CAST('2004-10-0' AS DATE)); ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CAST('2004-0-10' AS DATE)); @@ -262,6 +267,7 @@ ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE)); ERROR 22007: Truncated incorrect datetime value: '0000-00-00' INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col2) VALUES(CAST('2004-10-0 15:30' AS DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(CAST('2004-0-10 15:30' AS DATETIME)); @@ -269,7 +275,7 @@ ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' a INSERT INTO t1 (col2) VALUES(CAST('0000-00-00' AS DATETIME)); ERROR 22007: Truncated incorrect datetime value: '0000-00-00' INSERT INTO t1 (col3) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); -ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col3) VALUES(CAST('2004-10-0 15:30' AS DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1 INSERT INTO t1 (col3) VALUES(CAST('2004-0-10 15:30' AS DATETIME)); @@ -282,6 +288,7 @@ INSERT INTO t1 (col1) VALUES (CONVERT('2004-10-15',DATE)); INSERT INTO t1 (col2) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31' INSERT INTO t1 (col1) VALUES(CONVERT('2004-10-0' , DATE)); ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CONVERT('2004-0-10' , DATE)); @@ -289,6 +296,7 @@ ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE)); ERROR 22007: Truncated incorrect datetime value: '0000-00-00' INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col2) VALUES(CONVERT('2004-10-0 15:30',DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(CONVERT('2004-0-10 15:30',DATETIME)); @@ -296,7 +304,7 @@ ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' a INSERT INTO t1 (col2) VALUES(CONVERT('0000-00-00',DATETIME)); ERROR 22007: Truncated incorrect datetime value: '0000-00-00' INSERT INTO t1 (col3) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); -ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col3) VALUES(CONVERT('2004-10-0 15:30',DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1 INSERT INTO t1 (col3) VALUES(CONVERT('2004-0-10 15:30',DATETIME)); @@ -989,16 +997,16 @@ ERROR 23000: Column 'col2' cannot be null INSERT INTO t1 VALUES (103,'',NULL); ERROR 23000: Column 'col3' cannot be null UPDATE t1 SET col1=NULL WHERE col1 =100; -ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'col1' at row 1 +ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1 UPDATE t1 SET col2 =NULL WHERE col2 ='hello'; -ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'col2' at row 1 +ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1 UPDATE t1 SET col2 =NULL where col3 IS NOT NULL; -ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'col2' at row 1 +ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1 INSERT IGNORE INTO t1 values (NULL,NULL,NULL); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col1' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col2' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col3' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col3' at row 1 SELECT * FROM t1; col1 col2 col3 100 hello 2004-08-20 @@ -1023,11 +1031,11 @@ ERROR HY000: Field 'col2' doesn't have a default value INSERT INTO t1 (col1) SELECT 1; ERROR HY000: Field 'col2' doesn't have a default value INSERT INTO t1 SELECT 1,NULL; -ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'col2' at row 1 +ERROR 22004: Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1 INSERT IGNORE INTO t1 values (NULL,NULL); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col1' at row 1 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'col2' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col1' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'col2' at row 1 INSERT IGNORE INTO t1 (col1) values (3); Warnings: Warning 1364 Field 'col2' doesn't have a default value diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index ae929cf9c2e..4ee6d3088a5 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2888,6 +2888,55 @@ select 1 from dual where 1 < any (select 2 from dual); select 1 from dual where 1 < all (select 2 from dual where 1!=1); 1 1 +create table t1 (s1 char); +insert into t1 values (1),(2); +select * from t1 where (s1 < any (select s1 from t1)); +s1 +1 +select * from t1 where not (s1 < any (select s1 from t1)); +s1 +2 +select * from t1 where (s1 < ALL (select s1+1 from t1)); +s1 +1 +select * from t1 where not(s1 < ALL (select s1+1 from t1)); +s1 +2 +select * from t1 where (s1+1 = ANY (select s1 from t1)); +s1 +1 +select * from t1 where NOT(s1+1 = ANY (select s1 from t1)); +s1 +2 +select * from t1 where (s1 = ALL (select s1/s1 from t1)); +s1 +1 +select * from t1 where NOT(s1 = ALL (select s1/s1 from t1)); +s1 +2 +drop table t1; +create table t1 ( +retailerID varchar(8) NOT NULL, +statusID int(10) unsigned NOT NULL, +changed datetime NOT NULL, +UNIQUE KEY retailerID (retailerID, statusID, changed) +); +INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56"); +INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53"); +INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56"); +INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53"); +INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50"); +INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50"); +select * from t1 r1 +where (r1.retailerID,(r1.changed)) in +(SELECT r2.retailerId,(max(changed)) from t1 r2 +group by r2.retailerId); +retailerID statusID changed +0026 2 2006-01-06 12:25:53 +0037 2 2006-01-06 12:25:53 +0048 1 2006-01-06 12:37:50 +0059 1 2006-01-06 12:37:50 +drop table t1; create table t1 (df decimal(5,1)); insert into t1 values(1.1); insert into t1 values(2.2); diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result index 026bcb4b370..75aa339fb29 100644 --- a/mysql-test/r/subselect2.result +++ b/mysql-test/r/subselect2.result @@ -132,3 +132,15 @@ id select_type table type possible_keys key key_len ref rows Extra 5 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using index; Using where 6 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using index; Using where drop table t1, t2, t3, t4; +CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a int(10), PRIMARY KEY (a)) Engine=InnoDB; +INSERT INTO t2 VALUES (1); +CREATE TABLE t3 (a int(10), b int(10), c int(10), +PRIMARY KEY (a)) Engine=InnoDB; +INSERT INTO t3 VALUES (1,2,1); +SELECT t1.* FROM t1 WHERE (SELECT COUNT(*) FROM t3,t2 WHERE t3.c=t2.a +and t2.a='1' AND t1.a=t3.b) > 0; +a +2 +DROP TABLE t1,t2,t3; diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index f3e797d2344..c687d4c49c8 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -626,12 +626,51 @@ Trigger Event Table Statement Timing Created sql_mode Definer t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # root@localhost drop table t1; create table t1 (id int); +create trigger t1_ai after insert on t1 for each row reset query cache; +ERROR 0A000: RESET is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row reset master; +ERROR 0A000: RESET is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row reset slave; +ERROR 0A000: RESET is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush hosts; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush tables with read lock; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush logs; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush status; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush slave; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush master; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush des_key_file; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +create trigger t1_ai after insert on t1 for each row flush user_resources; +ERROR 0A000: FLUSH is not allowed in stored function or trigger create trigger t1_ai after insert on t1 for each row flush tables; ERROR 0A000: FLUSH is not allowed in stored function or trigger create trigger t1_ai after insert on t1 for each row flush privileges; ERROR 0A000: FLUSH is not allowed in stored function or trigger -create procedure p1() flush tables; +drop procedure if exists p1; create trigger t1_ai after insert on t1 for each row call p1(); +create procedure p1() flush tables; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() reset query cache; +insert into t1 values (0); +ERROR 0A000: RESET is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() reset master; +insert into t1 values (0); +ERROR 0A000: RESET is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() reset slave; +insert into t1 values (0); +ERROR 0A000: RESET is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush hosts; insert into t1 values (0); ERROR 0A000: FLUSH is not allowed in stored function or trigger drop procedure p1; @@ -639,6 +678,38 @@ create procedure p1() flush privileges; insert into t1 values (0); ERROR 0A000: FLUSH is not allowed in stored function or trigger drop procedure p1; +create procedure p1() flush tables with read lock; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush tables; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush logs; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush status; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush slave; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush master; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush des_key_file; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; +create procedure p1() flush user_resources; +insert into t1 values (0); +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop procedure p1; drop table t1; create table t1 (id int, data int, username varchar(16)); insert into t1 (id, data) values (1, 0); @@ -1089,4 +1160,17 @@ begin set @a:= 1; end| ERROR HY000: Triggers can not be created on system tables +use test| +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); +CREATE DEFINER=1234567890abcdefGHIKL@localhost +TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY +TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +DROP TABLE t1; +DROP TABLE t2; End of 5.0 tests diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 2281ed44e3f..f0ac00cedfa 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -572,4 +572,34 @@ def test t1 t1 a a 16 7 1 Y 0 0 63 a ` drop table t1; +create table bug15583(b BIT(8), n INT); +insert into bug15583 values(128, 128); +insert into bug15583 values(null, null); +insert into bug15583 values(0, 0); +insert into bug15583 values(255, 255); +select hex(b), bin(b), oct(b), hex(n), bin(n), oct(n) from bug15583; +hex(b) bin(b) oct(b) hex(n) bin(n) oct(n) +80 10000000 200 80 10000000 200 +NULL NULL NULL NULL NULL NULL +0 0 0 0 0 0 +FF 11111111 377 FF 11111111 377 +select hex(b)=hex(n) as should_be_onetrue, bin(b)=bin(n) as should_be_onetrue, oct(b)=oct(n) as should_be_onetrue from bug15583; +should_be_onetrue should_be_onetrue should_be_onetrue +1 1 1 +NULL NULL NULL +1 1 1 +1 1 1 +select hex(b + 0), bin(b + 0), oct(b + 0), hex(n), bin(n), oct(n) from bug15583; +hex(b + 0) bin(b + 0) oct(b + 0) hex(n) bin(n) oct(n) +80 10000000 200 80 10000000 200 +NULL NULL NULL NULL NULL NULL +0 0 0 0 0 0 +FF 11111111 377 FF 11111111 377 +select conv(b, 10, 2), conv(b + 0, 10, 2) from bug15583; +conv(b, 10, 2) conv(b + 0, 10, 2) +10000000 10000000 +NULL NULL +0 0 +11111111 11111111 +drop table bug15583; End of 5.0 tests diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 4fd220045c2..73b67a2241e 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -503,6 +503,8 @@ foobar boggle fish 10 drop table t1; create table t1 (id integer auto_increment unique,imagem LONGBLOB not null default ''); +Warnings: +Warning 1101 BLOB/TEXT column 'imagem' can't have a default value insert into t1 (id) values (1); select charset(load_file('../../std_data/words.dat')), @@ -788,3 +790,21 @@ NULL 616100000000 620000000000 drop table t1; +create table t1 (a text default ''); +Warnings: +Warning 1101 BLOB/TEXT column 'a' can't have a default value +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (default); +select * from t1; +a +NULL +drop table t1; +set @@sql_mode='TRADITIONAL'; +create table t1 (a text default ''); +ERROR 42000: BLOB/TEXT column 'a' can't have a default value +set @@sql_mode=''; +End of 5.0 tests diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 85f899be5d8..49e4827cb97 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -26,6 +26,8 @@ Table Op Msg_type Msg_text test.t1 check status OK delete from t1; insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000"); +Warnings: +Warning 1264 Out of range value adjusted for column 't' at row 5 insert into t1 values ("2003-003-03"); insert into t1 values ("20030102T131415"),("2001-01-01T01:01:01"), ("2001-1-1T1:01:01"); select * from t1; @@ -34,7 +36,7 @@ t 2069-12-31 00:00:00 1970-01-01 00:00:00 1999-12-31 00:00:00 -0000-01-01 00:00:00 +0000-00-00 00:00:00 0001-01-01 00:00:00 9999-12-31 00:00:00 2000-10-10 00:00:00 @@ -166,3 +168,14 @@ dt 0000-00-00 00:00:00 0000-00-00 00:00:00 drop table t1; +CREATE TABLE t1(a DATETIME NOT NULL); +INSERT INTO t1 VALUES ('20060606155555'); +SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555"); +a +2006-06-06 15:55:55 +PREPARE s FROM 'SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555")'; +EXECUTE s; +a +2006-06-06 15:55:55 +DROP PREPARE s; +DROP TABLE t1; diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 4caec152a1f..33f1ece0390 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -915,9 +915,13 @@ drop table t1; select cast('1.00000001335143196001808973960578441619873046875E-10' as decimal(30,15)); cast('1.00000001335143196001808973960578441619873046875E-10' as decimal(30,15)) 0.000000000100000 -select ln(14000) c1, convert(ln(14000),decimal(2,3)) c2, cast(ln(14000) as decimal(2,3)) c3; +select ln(14000) c1, convert(ln(14000),decimal(5,3)) c2, cast(ln(14000) as decimal(5,3)) c3; c1 c2 c3 9.5468126085974 9.547 9.547 +select convert(ln(14000),decimal(2,3)) c1; +ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column ''). +select cast(ln(14000) as decimal(2,3)) c1; +ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column ''). create table t1 (sl decimal(70,30)); ERROR 42000: Too big precision 70 specified for column 'sl'. Maximum is 65. create table t1 (sl decimal(32,31)); diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 1310a5b71dd..e949d734944 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -38,6 +38,9 @@ KEY (ulong), KEY (ulonglong,ulong), KEY (options,flags) ); +Warnings: +Warning 1101 BLOB/TEXT column 'mediumblob_col' can't have a default value +Warning 1101 BLOB/TEXT column 'longblob_col' can't have a default value show full fields from t1; Field Type Collation Null Key Default Extra Privileges Comment auto int(5) unsigned NULL NO PRI NULL auto_increment # @@ -54,7 +57,7 @@ ushort smallint(5) unsigned zerofill NULL NO MUL 00000 # umedium mediumint(8) unsigned NULL NO MUL 0 # ulong int(11) unsigned NULL NO MUL 0 # ulonglong bigint(13) unsigned NULL NO MUL 0 # -time_stamp timestamp NULL YES CURRENT_TIMESTAMP # +time_stamp timestamp NULL NO CURRENT_TIMESTAMP # date_field date NULL YES NULL # time_field time NULL YES NULL # date_time datetime NULL YES NULL # @@ -226,7 +229,7 @@ ushort smallint(5) unsigned zerofill NULL NO 00000 # umedium mediumint(8) unsigned NULL NO MUL 0 # ulong int(11) unsigned NULL NO MUL 0 # ulonglong bigint(13) unsigned NULL NO MUL 0 # -time_stamp timestamp NULL YES CURRENT_TIMESTAMP # +time_stamp timestamp NULL NO CURRENT_TIMESTAMP # date_field char(10) latin1_swedish_ci YES NULL # time_field time NULL YES NULL # date_time datetime NULL YES NULL # @@ -252,7 +255,7 @@ ushort smallint(5) unsigned zerofill NULL NO 00000 # umedium mediumint(8) unsigned NULL NO 0 # ulong int(11) unsigned NULL NO 0 # ulonglong bigint(13) unsigned NULL NO 0 # -time_stamp timestamp NULL YES 0000-00-00 00:00:00 # +time_stamp timestamp NULL NO 0000-00-00 00:00:00 # date_field char(10) latin1_swedish_ci YES NULL # time_field time NULL YES NULL # date_time datetime NULL YES NULL # diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 0817cc3b6c7..445ada578d0 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -201,9 +201,9 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra -t1 timestamp YES 2003-01-01 00:00:00 +t1 timestamp NO 2003-01-01 00:00:00 t2 datetime YES NULL -t3 timestamp YES 0000-00-00 00:00:00 +t3 timestamp NO 0000-00-00 00:00:00 drop table t1; create table t1 (t1 timestamp default now(), t2 datetime, t3 timestamp); SET TIMESTAMP=1000000002; @@ -225,9 +225,9 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra -t1 timestamp YES CURRENT_TIMESTAMP +t1 timestamp NO CURRENT_TIMESTAMP t2 datetime YES NULL -t3 timestamp YES 0000-00-00 00:00:00 +t3 timestamp NO 0000-00-00 00:00:00 drop table t1; create table t1 (t1 timestamp default '2003-01-01 00:00:00' on update now(), t2 datetime); SET TIMESTAMP=1000000004; @@ -251,7 +251,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra -t1 timestamp YES 2003-01-01 00:00:00 +t1 timestamp NO 2003-01-01 00:00:00 t2 datetime YES NULL drop table t1; create table t1 (t1 timestamp default now() on update now(), t2 datetime); @@ -276,7 +276,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra -t1 timestamp YES CURRENT_TIMESTAMP +t1 timestamp NO CURRENT_TIMESTAMP t2 datetime YES NULL drop table t1; create table t1 (t1 timestamp, t2 datetime, t3 timestamp); @@ -302,9 +302,9 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra -t1 timestamp YES CURRENT_TIMESTAMP +t1 timestamp NO CURRENT_TIMESTAMP t2 datetime YES NULL -t3 timestamp YES 0000-00-00 00:00:00 +t3 timestamp NO 0000-00-00 00:00:00 drop table t1; create table t1 (t1 timestamp default current_timestamp on update current_timestamp, t2 datetime); SET TIMESTAMP=1000000009; @@ -328,7 +328,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 show columns from t1; Field Type Null Key Default Extra -t1 timestamp YES CURRENT_TIMESTAMP +t1 timestamp NO CURRENT_TIMESTAMP t2 datetime YES NULL delete from t1; insert into t1 values ('2004-04-01 00:00:00', '2004-04-01 00:00:00'); @@ -493,3 +493,18 @@ a b c 6 NULL 2006-06-06 06:06:06 drop table t1; set time_zone= @@global.time_zone; +CREATE TABLE t1 ( +`id` int(11) NOT NULL auto_increment, +`username` varchar(80) NOT NULL default '', +`posted_on` timestamp NOT NULL default '0000-00-00 00:00:00', +PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1; +show fields from t1; +Field Type Null Key Default Extra +id int(11) NO PRI NULL auto_increment +username varchar(80) NO +posted_on timestamp NO 0000-00-00 00:00:00 +select is_nullable from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='t1' and COLUMN_NAME='posted_on'; +is_nullable +NO +drop table t1; diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result index e74850bba33..1d707b83a4d 100644 --- a/mysql-test/r/type_varchar.result +++ b/mysql-test/r/type_varchar.result @@ -422,3 +422,34 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test'); INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3)); DROP TABLE IF EXISTS t1; +drop table if exists t1, t2, t3; +create table t3 ( +id int(11), +en varchar(255) character set utf8, +cz varchar(255) character set utf8 +); +truncate table t3; +insert into t3 (id, en, cz) values +(1,'en string 1','cz string 1'), +(2,'en string 2','cz string 2'), +(3,'en string 3','cz string 3'); +create table t1 ( +id int(11), +name_id int(11) +); +insert into t1 (id, name_id) values (1,1), (2,3), (3,3); +create table t2 (id int(11)); +insert into t2 (id) values (1), (2), (3); +select t1.*, t2.id, t3.en, t3.cz from t1 left join t2 on t1.id=t2.id +left join t3 on t1.id=t3.id order by t3.id; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def test t1 t1 id id 3 11 1 Y 32768 0 63 +def test t1 t1 name_id name_id 3 11 1 Y 32768 0 63 +def test t2 t2 id id 3 11 1 Y 32768 0 63 +def test t3 t3 en en 253 255 11 Y 0 0 8 +def test t3 t3 cz cz 253 255 11 Y 0 0 8 +id name_id id en cz +1 1 1 en string 1 cz string 1 +2 3 2 en string 2 cz string 2 +3 3 3 en string 3 cz string 3 +drop table t1, t2, t3; diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index 484c42c41bf..8e37cca6aa9 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -93,6 +93,18 @@ NULL 0R FR DROP TABLE bug19904; +CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; +ERROR HY000: Incorrect usage of SONAME and DEFINER +CREATE DEFINER=someone@somewhere FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; +ERROR HY000: Incorrect usage of SONAME and DEFINER +create table t1(f1 int); +insert into t1 values(1),(2); +explain select myfunc_int(f1) from t1 order by 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +drop table t1; End of 5.0 tests. DROP FUNCTION metaphon; DROP FUNCTION myfunc_double; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 426387e04f5..42a3874db08 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -691,9 +691,9 @@ t1 CREATE TABLE `t1` ( `da` datetime default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; -create table t1 SELECT dt from t2 UNION select sc from t2; -select * from t1; -dt +create table t1 SELECT dt from t2 UNION select trim(sc) from t2; +select trim(dt) from t1; +trim(dt) 1972-10-22 11:50:00 testc show create table t1; @@ -732,7 +732,7 @@ tetetetetest show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `dt` longblob + `dt` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT sv from t2 UNION select b from t2; @@ -743,7 +743,7 @@ tetetetetest show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `sv` longblob + `sv` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT i from t2 UNION select d from t2 UNION select b from t2; @@ -755,7 +755,7 @@ tetetetetest show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `i` longblob + `i` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT sv from t2 UNION select tx from t2; @@ -766,7 +766,7 @@ teeeeeeeeeeeest show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `sv` longtext + `sv` text ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; create table t1 SELECT b from t2 UNION select tx from t2; @@ -777,7 +777,7 @@ teeeeeeeeeeeest show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `b` longblob + `b` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1,t2; create table t1 select 1 union select -1; @@ -1306,6 +1306,21 @@ id 5 99 drop table t1; +create table t1(f1 char(1), f2 char(5), f3 binary(1), f4 binary(5), f5 timestamp, f6 varchar(1) character set utf8 collate utf8_general_ci, f7 text); +create table t2 as select *, f6 as f8 from t1 union select *, f7 from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `f1` char(1) default NULL, + `f2` char(5) default NULL, + `f3` binary(1) default NULL, + `f4` binary(5) default NULL, + `f5` timestamp NOT NULL default '0000-00-00 00:00:00', + `f6` varchar(1) character set utf8 default NULL, + `f7` text, + `f8` mediumtext character set utf8 +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1, t2; (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union @@ -1351,3 +1366,8 @@ drop table t1; (select avg(1)) union (select avg(1)) union (select avg(1)); avg(1) NULL +select _utf8'12' union select _latin1'12345'; +12 +12 +12345 +End of 5.0 tests diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 7439f9132fb..1664a907c99 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -256,3 +256,48 @@ t1 CREATE TABLE `t1` ( `@first_var` longtext ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +set @a=18446744071710965857; +select @a; +@a +18446744071710965857 +CREATE TABLE `bigfailure` ( +`afield` BIGINT UNSIGNED NOT NULL +); +INSERT INTO `bigfailure` VALUES (18446744071710965857); +SELECT * FROM bigfailure; +afield +18446744071710965857 +select * from (SELECT afield FROM bigfailure) as b; +afield +18446744071710965857 +select * from bigfailure where afield = (SELECT afield FROM bigfailure); +afield +18446744071710965857 +select * from bigfailure where afield = 18446744071710965857; +afield +18446744071710965857 +select * from bigfailure where afield = 18446744071710965856+1; +afield +18446744071710965857 +SET @a := (SELECT afield FROM bigfailure); +SELECT @a; +@a +18446744071710965857 +SET @a := (select afield from (SELECT afield FROM bigfailure) as b); +SELECT @a; +@a +18446744071710965857 +SET @a := (select * from bigfailure where afield = (SELECT afield FROM bigfailure)); +SELECT @a; +@a +18446744071710965857 +drop table bigfailure; +create table t1(f1 int, f2 int); +insert into t1 values (1,2),(2,3),(3,1); +select @var:=f2 from t1 group by f1 order by f2 desc limit 1; +@var:=f2 +3 +select @var; +@var +3 +drop table t1; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 7d2ab63ca77..f70547cd4a8 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -193,7 +193,7 @@ c d 2 5 3 10 drop view v100; -ERROR 42S02: Unknown table 'test.v100' +ERROR 42S02: Unknown table 'v100' drop view t1; ERROR HY000: 'test.t1' is not VIEW drop table v1; @@ -1495,7 +1495,7 @@ insert into v3(b) values (10); insert into v3(a) select a from t2; insert into v3(b) select b from t2; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2 insert into v3(a) values (1) on duplicate key update a=a+10000+VALUES(a); select * from t1; a b @@ -2774,3 +2774,146 @@ Field Type Null Key Default Extra COALESCE(i,j) int(11) YES NULL DROP VIEW v1; DROP TABLE t1,t2; +CREATE TABLE t1 (s varchar(10)); +INSERT INTO t1 VALUES ('yadda'), ('yady'); +SELECT TRIM(BOTH 'y' FROM s) FROM t1; +TRIM(BOTH 'y' FROM s) +adda +ad +CREATE VIEW v1 AS SELECT TRIM(BOTH 'y' FROM s) FROM t1; +SELECT * FROM v1; +TRIM(BOTH 'y' FROM s) +adda +ad +DROP VIEW v1; +SELECT TRIM(LEADING 'y' FROM s) FROM t1; +TRIM(LEADING 'y' FROM s) +adda +ady +CREATE VIEW v1 AS SELECT TRIM(LEADING 'y' FROM s) FROM t1; +SELECT * FROM v1; +TRIM(LEADING 'y' FROM s) +adda +ady +DROP VIEW v1; +SELECT TRIM(TRAILING 'y' FROM s) FROM t1; +TRIM(TRAILING 'y' FROM s) +yadda +yad +CREATE VIEW v1 AS SELECT TRIM(TRAILING 'y' FROM s) FROM t1; +SELECT * FROM v1; +TRIM(TRAILING 'y' FROM s) +yadda +yad +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (x INT, y INT); +CREATE ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x` from `t1` +ALTER VIEW v1 AS SELECT x, y FROM t1; +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x`,`t1`.`y` AS `y` from `t1` +DROP VIEW v1; +DROP TABLE t1; +CREATE TABLE t1 (s1 char); +INSERT INTO t1 VALUES ('Z'); +CREATE VIEW v1 AS SELECT s1 collate latin1_german1_ci AS col FROM t1; +CREATE VIEW v2 (col) AS SELECT s1 collate latin1_german1_ci FROM t1; +INSERT INTO v1 (col) VALUES ('b'); +INSERT INTO v2 (col) VALUES ('c'); +SELECT s1 FROM t1; +s1 +Z +b +c +DROP VIEW v1, v2; +DROP TABLE t1; +CREATE TABLE t1 (id INT); +CREATE VIEW v1 AS SELECT id FROM t1; +SHOW TABLES; +Tables_in_test +t1 +v1 +DROP VIEW v2,v1; +ERROR 42S02: Unknown table 'v2' +SHOW TABLES; +Tables_in_test +t1 +CREATE VIEW v1 AS SELECT id FROM t1; +DROP VIEW t1,v1; +ERROR HY000: 'test.t1' is not VIEW +SHOW TABLES; +Tables_in_test +t1 +DROP TABLE t1; +DROP VIEW IF EXISTS v1; +CREATE DATABASE bug21261DB; +USE bug21261DB; +CREATE TABLE t1 (x INT); +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +GRANT INSERT, UPDATE ON v1 TO 'user21261'@'localhost'; +GRANT INSERT, UPDATE ON t1 TO 'user21261'@'localhost'; +CREATE TABLE t2 (y INT); +GRANT SELECT ON t2 TO 'user21261'@'localhost'; +INSERT INTO v1 (x) VALUES (5); +UPDATE v1 SET x=1; +GRANT SELECT ON v1 TO 'user21261'@'localhost'; +GRANT SELECT ON t1 TO 'user21261'@'localhost'; +UPDATE v1,t2 SET x=1 WHERE x=y; +SELECT * FROM t1; +x +1 +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user21261'@'localhost'; +DROP USER 'user21261'@'localhost'; +DROP VIEW v1; +DROP TABLE t1; +DROP DATABASE bug21261DB; +USE test; +create table t1 (f1 datetime); +create view v1 as select * from t1 where f1 between now() and now() + interval 1 minute; +show create view v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where (`t1`.`f1` between now() and (now() + interval 1 minute)) +drop view v1; +drop table t1; +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP VIEW IF EXISTS v2; +CREATE TABLE t1(a INT, b INT); +CREATE DEFINER=1234567890abcdefGHIKL@localhost +VIEW v1 AS SELECT a FROM t1; +ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16) +CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY +VIEW v2 AS SELECT b FROM t1; +ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60) +DROP TABLE t1; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP VIEW IF EXISTS v1, v2; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (i INT); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE FUNCTION f1() RETURNS INT +BEGIN +INSERT INTO v1 VALUES (0); +RETURN 0; +END | +SELECT f1(); +f1() +0 +CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t1; +CREATE FUNCTION f2() RETURNS INT +BEGIN +INSERT INTO v2 VALUES (0); +RETURN 0; +END | +SELECT f2(); +ERROR HY000: The target table v2 of the INSERT is not updatable +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP VIEW v1, v2; +DROP TABLE t1; +End of 5.0 tests. diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 59be512d5a6..283a0661721 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -72,7 +72,7 @@ drop table t1; create table t1(a tinyint, b int not null, c date, d char(5)); load data infile '../std_data_ln/warnings_loaddata.dat' into table t1 fields terminated by ','; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'b' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'b' at row 2 Warning 1265 Data truncated for column 'd' at row 3 Warning 1265 Data truncated for column 'c' at row 4 Warning 1261 Row 5 doesn't contain data for all columns @@ -86,7 +86,7 @@ drop table t1; create table t1(a tinyint NOT NULL, b tinyint unsigned, c char(5)); insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test'); Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 1 Warning 1264 Out of range value adjusted for column 'b' at row 2 Warning 1265 Data truncated for column 'c' at row 2 Warning 1264 Out of range value adjusted for column 'a' at row 3 @@ -99,7 +99,7 @@ Warning 1265 Data truncated for column 'c' at row 2 alter table t1 add d char(2); update t1 set a=NULL where a=10; Warnings: -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 2 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 2 update t1 set c='mysql ab' where c='test'; Warnings: Warning 1265 Data truncated for column 'c' at row 4 @@ -115,7 +115,7 @@ Warnings: Warning 1265 Data truncated for column 'b' at row 1 Warning 1265 Data truncated for column 'b' at row 2 Warning 1265 Data truncated for column 'b' at row 3 -Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'a' at row 4 +Warning 1263 Column was set to data type implicit default; NULL supplied for NOT NULL column 'a' at row 4 Warning 1265 Data truncated for column 'b' at row 4 insert into t2(b) values('mysqlab'); Warnings: diff --git a/mysql-test/std_data/14897.frm b/mysql-test/std_data/14897.frm Binary files differnew file mode 100644 index 00000000000..aff11b467b0 --- /dev/null +++ b/mysql-test/std_data/14897.frm diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index fbe1ee2b8c8..0e9e141f6d8 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -133,8 +133,6 @@ select min(a), min(case when 1=1 then a else NULL end), from t1 where b=3 group by b; drop table t1; -# End of 4.1 tests - # # Tests for bug #9939: conversion of the arguments for COALESCE and IFNULL @@ -154,3 +152,4 @@ SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM, FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM; DROP TABLE t1,t2; +# End of 4.1 tests diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index 533da542855..ecc92ed01d1 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -204,7 +204,19 @@ SELECT CAST(v AS DECIMAL), CAST(tt AS DECIMAL), CAST(t AS DECIMAL), CAST(mt AS DECIMAL), CAST(lt AS DECIMAL) from t1; DROP TABLE t1; -# Bug @10237 (CAST(NULL DECIMAL) crashes server) + +# +# Bug #10237 (CAST(NULL DECIMAL) crashes server) # select cast(NULL as decimal(6)) as t1; + +# +# Bug #17903: cast to char results in binary +# +set names latin1; +select hex(cast('a' as char(2) binary)); +select hex(cast('a' as binary(2))); +select hex(cast('a' as char(2) binary)); + +--echo End of 5.0 tests diff --git a/mysql-test/t/compare.test b/mysql-test/t/compare.test index a42ba5ac88a..337035a8095 100644 --- a/mysql-test/t/compare.test +++ b/mysql-test/t/compare.test @@ -37,3 +37,12 @@ SELECT CHAR(31) = '', '' = CHAR(31); SELECT CHAR(30) = '', '' = CHAR(30); # End of 4.1 tests + +# +#Bug #21159: Optimizer: wrong result after AND with different data types +# +create table t1 (a tinyint(1),b binary(1)); +insert into t1 values (0x01,0x01); +select * from t1 where a=b; +select * from t1 where a=b and b=0x01; +drop table if exists t1; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index a028f6ced6d..8bd48b7da2c 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1384,3 +1384,27 @@ truncate table t1; -- truncate --disable_info drop table t1; +# +# Bug #15205 Select from CSV table without the datafile causes crash +# +# NOTE: the bug is not deterministic + +# The crash happens because the necessary cleanup after an error wasn't +# performed. Namely, the table share, inserted in the hash during table +# open, was not deleted from hash. At the same time the share was freed +# when an error was encountered. Thus, subsequent access to the hash +# resulted in scanning through deleted memory and we were geting a crash. +# that's why we need two tables in the bugtest + +create table bug15205 (val int(11) default null) engine=csv; +create table bug15205_2 (val int(11) default null) engine=csv; +--exec rm $MYSQLTEST_VARDIR/master-data/test/bug15205.CSV +# system error (can't open the datafile) +--error ER_GET_ERRNO +select * from bug15205; +select * from bug15205_2; +--exec touch $MYSQLTEST_VARDIR/master-data/test/bug15205.CSV +select * from bug15205; +drop table bug15205; +drop table bug15205_2; + diff --git a/mysql-test/t/ctype_cp1250_ch.test b/mysql-test/t/ctype_cp1250_ch.test index 2d1e5f0bf9d..65550e0c193 100644 --- a/mysql-test/t/ctype_cp1250_ch.test +++ b/mysql-test/t/ctype_cp1250_ch.test @@ -44,4 +44,14 @@ INSERT INTO t1 VALUES (NULL, 'aaaaaaa'); select * from t1 where str like 'aa%'; drop table t1; +# +# Bug#19741 segfault with cp1250 charset + like + primary key + 64bit os +# +set names cp1250; +create table t1 (a varchar(15) collate cp1250_czech_cs NOT NULL, primary key(a)); +insert into t1 values("abcdefghá"); +insert into t1 values("ááèè"); +select a from t1 where a like "abcdefghá"; +drop table t1; + # End of 4.1 tests diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index 2d6b55600b1..c18c46b6b08 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -187,4 +187,16 @@ select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1; #select case c1 when 'ß' then 'ß' when 'ö' then 'ö' else 'c' end from t1; #select export_set(5,c1,'ö'), export_set(5,'ö',c1) from t1; drop table t1; -# End of 4.1 tests + +# +# Bug 20695: problem with field default value's character set +# + +set names koi8r; +create table t1(a char character set cp1251 default _koi8r 0xFF); +show create table t1; +drop table t1; +--error 1067 +create table t1(a char character set latin1 default _cp1251 0xFF); + +--echo End of 4.1 tests diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index eea0b06b224..8116d39e3db 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -465,7 +465,51 @@ INSERT INTO t1 VALUES (1, 'ZZZZZ'), (1, 'ZZZ'), (2, 'ZZZ'), (2, 'ZZZZZ'); SELECT id, MIN(s) FROM t1 GROUP BY id; DROP TABLE t1; -# End of 4.1 tests + +# +# Bug #20536: md5() with GROUP BY and UCS2 return different results on myisam/innodb +# + +--disable_warnings +drop table if exists bug20536; +--enable_warnings + +set names latin1; +create table bug20536 (id bigint not null auto_increment primary key, name +varchar(255) character set ucs2 not null); +insert into `bug20536` (`id`,`name`) values (1, _latin1 x'7465737431'), (2, "'test\\_2'"); +select md5(name) from bug20536; +select sha1(name) from bug20536; +select make_set(3, name, upper(name)) from bug20536; +select export_set(5, name, upper(name)) from bug20536; +select export_set(5, name, upper(name), ",", 5) from bug20536; + +# Some broken functions: add these tests just to document current behavior. + +# PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would +# not be backwards compatible in all cases, so it's best to leave it alone +select password(name) from bug20536; +select old_password(name) from bug20536; + +# Disable test case as encrypt relies on 'crypt' function. +# "decrypt" is noramlly tested in func_crypt.test which have a +# "have_crypt.inc" test +--disable_parsing +# ENCRYPT relies on OS function crypt() which takes a NUL-terminated string; it +# doesn't return good results for strings with embedded 0 bytes. It won't be +# fixed unless we choose to re-implement the crypt() function ourselves to take +# an extra size_t string_length argument. +select encrypt(name, 'SALT') from bug20536; +--enable_parsing + +# QUOTE doesn't work with UCS2 data. It would require a total rewrite +# of Item_func_quote::val_str(), which isn't worthwhile until UCS2 is +# supported fully as a client character set. +select quote(name) from bug20536; + +drop table bug20536; + +--echo End of 4.1 tests # # Conversion from an UCS2 string to a decimal column @@ -497,3 +541,5 @@ create table t1(a blob, b text charset utf8, c text charset ucs2); select data_type, character_octet_length, character_maximum_length from information_schema.columns where table_name='t1'; drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 77b76a14171..b6137d5f084 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -728,6 +728,24 @@ select repeat(_utf8'+',3) as h union select NULL; select ifnull(NULL, _utf8'string'); # +# Bug#9509 Optimizer: wrong result after AND with comparisons +# +set names utf8; +create table t1 (s1 char(5) character set utf8 collate utf8_lithuanian_ci); +insert into t1 values ('I'),('K'),('Y'); +select * from t1 where s1 < 'K' and s1 = 'Y'; +select * from t1 where 'K' > s1 and s1 = 'Y'; +drop table t1; + +create table t1 (s1 char(5) character set utf8 collate utf8_czech_ci); +insert into t1 values ('c'),('d'),('h'),('ch'),('CH'),('cH'),('Ch'),('i'); +select * from t1 where s1 > 'd' and s1 = 'CH'; +select * from t1 where 'd' < s1 and s1 = 'CH'; +select * from t1 where s1 = 'cH' and s1 <> 'ch'; +select * from t1 where 'cH' = s1 and s1 <> 'ch'; +drop table t1; + +# # Bug#10714: Inserting double value into utf8 column crashes server # create table t1 (a varchar(255)) default character set utf8; @@ -879,6 +897,17 @@ DROP TABLE t2; DROP TABLE t1; # +# Bug#17313: N'xxx' and _utf8'xxx' are not equivalent +# +CREATE TABLE t1 (item varchar(255)) default character set utf8; +INSERT INTO t1 VALUES (N'\\'); +INSERT INTO t1 VALUES (_utf8'\\'); +INSERT INTO t1 VALUES (N'Cote d\'Ivoire'); +INSERT INTO t1 VALUES (_utf8'Cote d\'Ivoire'); +SELECT item FROM t1 ORDER BY item; +DROP TABLE t1; + +# # Bug#17705: Corruption of compressed index when index length changes between # 254 and 256 # @@ -1026,6 +1055,37 @@ ALTER TABLE t1 ADD KEY idx (tid,val(11)); SELECT * FROM t1 WHERE tid=72 and val LIKE 'VOLNÝ ADSL'; DROP TABLE t1; + +# +# Bug 20709: problem with utf8 fields in temporary tables +# + +create table t1(a char(200) collate utf8_unicode_ci NOT NULL default '') + default charset=utf8 collate=utf8_unicode_ci; +insert into t1 values (unhex('65')), (unhex('C3A9')), (unhex('65')); +explain select distinct a from t1; +select distinct a from t1; +explain select a from t1 group by a; +select a from t1 group by a; +drop table t1; + +# +# Bug#20393: User name truncation in mysql client +# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte +# +set names utf8; +#create user юзер_юзер@localhost; +grant select on test.* to юзер_юзер@localhost; +--exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; + +create database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45; +use имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45; +select database(); +drop database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45; +use test; + # End of 4.1 tests # diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 4284bd2a06d..677ffaa2860 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -171,3 +171,14 @@ delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; # This should be empty select * from t3; drop table t1,t2,t3; + +# +# Bug #8143: deleting '0000-00-00' values using IS NULL +# + +create table t1(a date not null); +insert into t1 values (0); +select * from t1 where a is null; +delete from t1 where a is null; +select count(*) from t1; +drop table t1; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 61250a7105e..e517380ba9b 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -385,6 +385,17 @@ insert into t1 values (1, "line number one"), (2, "line number two"), (3, "line select distinct id, IFNULL(dsc, '-') from t1; drop table t1; +# +# Bug 21456: SELECT DISTINCT(x) produces incorrect results when using order by +# +CREATE TABLE t1 (a int primary key, b int); + +INSERT INTO t1 (a,b) values (1,1), (2,3), (3,2); + +explain SELECT DISTINCT a, b FROM t1 ORDER BY b; +SELECT DISTINCT a, b FROM t1 ORDER BY b; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index 7cd943d46da..a1451773e90 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -81,3 +81,44 @@ show tables; drop table t1; # End of 4.1 tests + + +# +# Test for bug#21216 "Simultaneous DROP TABLE and SHOW OPEN TABLES causes +# server to crash". Crash (caused by failed assertion in 5.0 or by null +# pointer dereference in 5.1) happened when one ran SHOW OPEN TABLES +# while concurrently doing DROP TABLE (or RENAME TABLE, CREATE TABLE LIKE +# or any other command that takes name-lock) in other connection. +# +# Also includes test for similar bug#12212 "Crash that happens during +# removing of database name from cache" reappeared in 5.1 as bug#19403 +# In its case crash happened when one concurrently executed DROP DATABASE +# and one of name-locking command. +# +--disable_warnings +drop database if exists mysqltest; +drop table if exists t1; +--enable_warnings +create table t1 (i int); +lock tables t1 read; +create database mysqltest; +connect (addconroot1, localhost, root,,); +--send drop table t1 +connect (addconroot2, localhost, root,,); +# Server should not crash in any of the following statements +--disable_result_log +show open tables; +--enable_result_log +--send drop database mysqltest +connection default; +select 1; +unlock tables; +connection addconroot1; +--reap +connection addconroot2; +--reap +disconnect addconroot1; +disconnect addconroot2; +connection default; + +--echo End of 5.0 tests diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index 38beab605fd..c2218b3451b 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -1499,4 +1499,49 @@ drop table t1; connection master; drop table t1; +# +# BUG #15133: unique index with nullable value not accepted in federated table +# + +connection slave; +--disable_warnings +DROP TABLE IF EXISTS federated.test; +CREATE TABLE federated.test ( + `i` int(11) NOT NULL, + `j` int(11) NOT NULL, + `c` varchar(30) default NULL, + PRIMARY KEY (`i`,`j`), + UNIQUE KEY `i` (`i`,`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +--enable_warnings + +connection master; +--disable_warnings +DROP TABLE IF EXISTS federated.test1; +DROP TABLE IF EXISTS federated.test2; +--enable_warnings + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval create table federated.test1 ( + i int not null, + j int not null, + c varchar(30), + primary key (i,j), + unique key (i, c)) +engine = federated +connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/test'; + +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval create table federated.test2 ( + i int default null, + j int not null, + c varchar(30), + key (i)) +engine = federated +connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/test'; +drop table federated.test1, federated.test2; + +connection slave; +drop table federated.test; + source include/federated_cleanup.inc; diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 4ae749f2343..eeb5d509b94 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -57,3 +57,17 @@ select uncompress(a), uncompressed_length(a) from t1; drop table t1; # End of 4.1 tests + +# +# Bug #18539: uncompress(d) is null: impossible? +# +create table t1 (a varchar(32) not null); +insert into t1 values ('foo'); +explain select * from t1 where uncompress(a) is null; +select * from t1 where uncompress(a) is null; +explain select *, uncompress(a) from t1; +select *, uncompress(a) from t1; +select *, uncompress(a), uncompress(a) is null from t1; +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index fbfdfa3b5d0..98c21986aa9 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -433,3 +433,17 @@ create table t1 (c1 varchar(10), c2 int); select charset(group_concat(c1 order by c2)) from t1; drop table t1; +# +# Bug #16712: group_concat returns odd string instead of intended result +# +CREATE TABLE t1 (a INT(10), b LONGTEXT, PRIMARY KEY (a)); + +SET GROUP_CONCAT_MAX_LEN = 20000000; + +INSERT INTO t1 VALUES (1,REPEAT(CONCAT('A',CAST(CHAR(0) AS BINARY),'B'), 40000)); +INSERT INTO t1 SELECT a + 1, b FROM t1; + +SELECT a, CHAR_LENGTH(b) FROM t1; +SELECT CHAR_LENGTH( GROUP_CONCAT(b) ) FROM t1; +SET GROUP_CONCAT_MAX_LEN = 1024; +DROP TABLE t1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index e8c5fa18a25..c2dd77e662a 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -660,3 +660,30 @@ SELECT SUM(a) FROM t1 GROUP BY b/c; DROP TABLE t1; set div_precision_increment= @sav_dpi; +# +# Bug #20868: Client connection is broken on SQL query error +# +CREATE TABLE t1 (a INT PRIMARY KEY, b INT); +INSERT INTO t1 VALUES (1,1), (2,2); + +CREATE TABLE t2 (a INT PRIMARY KEY, b INT); +INSERT INTO t2 VALUES (1,1), (3,3); + +SELECT SQL_NO_CACHE + (SELECT SUM(c.a) FROM t1 ttt, t2 ccc + WHERE ttt.a = ccc.b AND ttt.a = t.a GROUP BY ttt.a) AS minid +FROM t1 t, t2 c WHERE t.a = c.b; + +DROP TABLE t1,t2; + +# +# Bug #10966: Variance functions return wrong data type +# + +create table t1 select variance(0); +show create table t1; +drop table t1; +create table t1 select stddev(0); +show create table t1; +drop table t1; + diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 0475dd4bdb6..52a5512d070 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -78,7 +78,13 @@ connection default; DROP TABLE t1; -# End of 4.1 tests +# +# Bug #21531: EXPORT_SET() doesn't accept args with coercible character sets +# +select export_set(3, _latin1'foo', _utf8'bar', ',', 4); + +--echo End of 4.1 tests + # # Test for BUG#9535 @@ -87,7 +93,9 @@ create table t1 as select uuid(), length(uuid()); show create table t1; drop table t1; +# # Bug #6760: Add SLEEP() function +# create table t1 (a timestamp default '2005-05-05 01:01:01', b timestamp default '2005-05-05 01:01:01'); insert into t1 set a = now(); @@ -117,4 +125,4 @@ drop table t2; drop table t1; set global query_cache_size=default; -# End of 5.0 tests +--echo End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 0fb866cf370..8753db0ebe1 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -706,6 +706,21 @@ SELECT a, CONCAT(a,' ',a) AS c FROM t1 INSTR(REVERSE(CONCAT(a,' ',a))," ")) = a; DROP TABLE t1; + +# +# Bug#17526: WRONG PRINT for TRIM FUNCTION with two arguments +# + +CREATE TABLE t1 (s varchar(10)); +INSERT INTO t1 VALUES ('yadda'), ('yaddy'); + +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(s) > 'ab'; +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM('y' FROM s) > 'ab'; +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(LEADING 'y' FROM s) > 'ab'; +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(TRAILING 'y' FROM s) > 'ab'; +EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(BOTH 'y' FROM s) > 'ab'; + +DROP TABLE t1; --echo End of 4.1 tests diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index f2ff47704c9..0ea89cd0913 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -108,9 +108,6 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3; select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3; -# End of 4.1 tests - -# # Bug#6726: NOT BETWEEN parse failure # create table t1 (a int, b int); @@ -127,3 +124,5 @@ SELECT GREATEST(1,NULL) FROM DUAL; SELECT LEAST('xxx','aaa',NULL,'yyy') FROM DUAL; SELECT LEAST(1.1,1.2,NULL,1.0) FROM DUAL; SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL; + +# End of 4.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 6aaf51b0acb..be09b00ad46 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -318,6 +318,37 @@ select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1, timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4; +# bug 16226 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:27'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:28'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:29'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:27'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:28'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:29'); + +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:27'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:28'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:29'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:27'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:28'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:29'); + +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:27'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:28'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:29'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:27'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:28'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:29'); + +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:27'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:28'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:29'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:27'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:28'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29'); + +# end of bug + select date_add(time,INTERVAL 1 SECOND) from t1; drop table t1; @@ -415,7 +446,25 @@ create table t1 select now() - now(), curtime() - curtime(), show create table t1; drop table t1; -# End of 4.1 tests +# +# Bug #19844 time_format in Union truncates values +# + +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%H') As H); +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 DAY)),'%k') As H); +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%H') As H); + +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H) +union +(select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H); + +--echo End of 4.1 tests explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; @@ -534,3 +583,21 @@ DROP TABLE t1,t2; # Restore timezone to default set time_zone= @@global.time_zone; + +# +# 21913: DATE_FORMAT() Crashes mysql server if I use it through +# mysql-connector-j driver. +# + +SET NAMES latin1; +SET character_set_results = NULL; +SHOW VARIABLES LIKE 'character_set_results'; + +CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); +INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); + +SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; + +DROP TABLE testBug8868; + +SET NAMES DEFAULT; diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 4c6ff9b2fe7..7bba34be3ff 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -281,7 +281,7 @@ INSERT INTO t1 VALUES(GeomFromText('POINT(580848489 219587743)')); INSERT INTO t1 VALUES(GeomFromText('POINT(11247614 782797569)')); drop table t1; -create table t1 select POINT(1,3); +create table t1 select GeomFromWKB(POINT(1,3)); show create table t1; drop table t1; @@ -416,3 +416,9 @@ select * from t1; select asbinary(g) from t1; --disable_metadata drop table t1; + + +create table t1 select GeomFromText('point(1 1)'); +desc t1; +drop table t1; + diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index a9d52f559ca..d3781d58780 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -362,6 +362,8 @@ revoke all on mysqltest_2.t2 from mysqltest_3@localhost; #test the db/table level privileges grant all on mysqltest_2.* to mysqltest_3@localhost; grant select on *.* to mysqltest_3@localhost; +# Next grant is needed to trigger bug#7391. Do not optimize! +grant select on mysqltest_2.t1 to mysqltest_3@localhost; flush privileges; disconnect conn1; connect (conn2,localhost,mysqltest_3,,); @@ -680,4 +682,185 @@ drop table t2; drop table t1; +# +# Bug#20214: Incorrect error when user calls SHOW CREATE VIEW on non +# privileged view +# + +connection master; + +CREATE DATABASE mysqltest3; +use mysqltest3; + +CREATE TABLE t_nn (c1 INT); +CREATE VIEW v_nn AS SELECT * FROM t_nn; + +CREATE DATABASE mysqltest2; +use mysqltest2; + +CREATE TABLE t_nn (c1 INT); +CREATE VIEW v_nn AS SELECT * FROM t_nn; +CREATE VIEW v_yn AS SELECT * FROM t_nn; +CREATE VIEW v_gy AS SELECT * FROM t_nn; +CREATE VIEW v_ny AS SELECT * FROM t_nn; +CREATE VIEW v_yy AS SELECT * FROM t_nn WHERE c1=55; + +GRANT SHOW VIEW ON mysqltest2.v_ny TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +GRANT SELECT ON mysqltest2.v_yn TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +GRANT SELECT ON mysqltest2.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; +GRANT SHOW VIEW,SELECT ON mysqltest2.v_yy TO 'mysqltest_1'@'localhost' IDENTIFIED BY 'mysqltest_1'; + +connect (mysqltest_1, localhost, mysqltest_1, mysqltest_1,); + +# fail because of missing SHOW VIEW (have generic SELECT) +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE VIEW mysqltest2.v_nn; +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE TABLE mysqltest2.v_nn; + + + +# fail because of missing SHOW VIEW +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE VIEW mysqltest2.v_yn; +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE TABLE mysqltest2.v_yn; + + + +# succeed (despite of missing SELECT, having SHOW VIEW bails us out) +SHOW CREATE TABLE mysqltest2.v_ny; + +# succeed (despite of missing SELECT, having SHOW VIEW bails us out) +SHOW CREATE VIEW mysqltest2.v_ny; + + + +# fail because of missing (specific or generic) SELECT +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE TABLE mysqltest3.t_nn; + +# fail because of missing (specific or generic) SELECT (not because it's not a view!) +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE VIEW mysqltest3.t_nn; + + + +# fail because of missing missing (specific or generic) SELECT (and SHOW VIEW) +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE VIEW mysqltest3.v_nn; +--error ER_TABLEACCESS_DENIED_ERROR +SHOW CREATE TABLE mysqltest3.v_nn; + + + +# succeed thanks to generic SELECT +SHOW CREATE TABLE mysqltest2.t_nn; + +# fail because it's not a view! (have generic SELECT though) +--error ER_WRONG_OBJECT +SHOW CREATE VIEW mysqltest2.t_nn; + + + +# succeed, have SELECT and SHOW VIEW +SHOW CREATE VIEW mysqltest2.v_yy; + +# succeed, have SELECT and SHOW VIEW +SHOW CREATE TABLE mysqltest2.v_yy; + + + +#clean-up +connection master; + +# succeed, we're root +SHOW CREATE TABLE mysqltest2.v_nn; +SHOW CREATE VIEW mysqltest2.v_nn; + +SHOW CREATE TABLE mysqltest2.t_nn; + +# fail because it's not a view! +--error ER_WRONG_OBJECT +SHOW CREATE VIEW mysqltest2.t_nn; + + + +DROP VIEW mysqltest2.v_nn; +DROP VIEW mysqltest2.v_yn; +DROP VIEW mysqltest2.v_ny; +DROP VIEW mysqltest2.v_yy; + +DROP TABLE mysqltest2.t_nn; + +DROP DATABASE mysqltest2; + + + +DROP VIEW mysqltest3.v_nn; +DROP TABLE mysqltest3.t_nn; + +DROP DATABASE mysqltest3; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost'; +DROP USER 'mysqltest_1'@'localhost'; + +# restore the original database +use test; + +# +# Bug #10668: CREATE USER does not enforce username length limit +# +--error ER_WRONG_STRING_LENGTH +create user mysqltest1_thisisreallytoolong; + +# +# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause. +# +# These checks are intended to ensure that appropriate errors are risen when +# illegal user name or hostname is specified in user-clause of GRANT/REVOKE +# statements. +# + +# Working with database-level privileges. + +--error ER_WRONG_STRING_LENGTH +GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost; + +--error ER_WRONG_STRING_LENGTH +GRANT CREATE ON mysqltest.* TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; + +--error ER_WRONG_STRING_LENGTH +REVOKE CREATE ON mysqltest.* FROM 1234567890abcdefGHIKL@localhost; + +--error ER_WRONG_STRING_LENGTH +REVOKE CREATE ON mysqltest.* FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; + +# Working with table-level privileges. + +--error ER_WRONG_STRING_LENGTH +GRANT CREATE ON t1 TO 1234567890abcdefGHIKL@localhost; + +--error ER_WRONG_STRING_LENGTH +GRANT CREATE ON t1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; + +--error ER_WRONG_STRING_LENGTH +REVOKE CREATE ON t1 FROM 1234567890abcdefGHIKL@localhost; + +--error ER_WRONG_STRING_LENGTH +REVOKE CREATE ON t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; + +# Working with routine-level privileges. + +--error ER_WRONG_STRING_LENGTH +GRANT EXECUTE ON PROCEDURE p1 TO 1234567890abcdefGHIKL@localhost; + +--error ER_WRONG_STRING_LENGTH +GRANT EXECUTE ON PROCEDURE p1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; + +--error ER_WRONG_STRING_LENGTH +REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost; +--error ER_WRONG_STRING_LENGTH +REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY; +--echo End of 5.0 tests diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 2b9a273df7e..66128e56515 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -188,6 +188,24 @@ disconnect con9; connection default; # +# Bug# 16180 - Setting SQL_LOG_OFF without SUPER privilege is silently ignored +# +create database mysqltest_1; +grant select, insert, update on `mysqltest\_1`.* to mysqltest_1@localhost; +connect (con10,localhost,mysqltest_1,,); +connection con10; +--error 1227 +set sql_log_off = 1; +--error 1227 +set sql_log_bin = 0; +disconnect con10; +connection default; +delete from mysql.user where user like 'mysqltest\_1'; +delete from mysql.db where user like 'mysqltest\_1'; +drop database mysqltest_1; +flush privileges; + +# End of 4.1 tests # Create and drop user # set sql_mode='maxdb'; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index fb9835c5d7f..8a514108dc3 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -632,3 +632,38 @@ group by t1.c1; show warnings; drop table t1, t2; +# +# Bug #20466: a view is mixing data when there's a trigger on the table +# +CREATE TABLE t1 (a tinyint(3), b varchar(255), PRIMARY KEY (a)); + +INSERT INTO t1 VALUES (1,'-----'), (6,'Allemagne'), (17,'Autriche'), + (25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France'); + +CREATE TABLE t2 (a tinyint(3), b tinyint(3), PRIMARY KEY (a), KEY b (b)); + +INSERT INTO t2 VALUES (1,1), (2,1), (6,6), (18,17), (15,25), (16,25), + (17,25), (10,54), (5,62),(3,68); + +CREATE VIEW v1 AS select t1.a, concat(t1.b,'') AS b, t1.b as real_b from t1; + +explain +SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1 +where t2.b=v1.a GROUP BY t2.b; +SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1 +where t2.b=v1.a GROUP BY t2.b; + +DROP VIEW v1; +DROP TABLE t1,t2; + +# +# Bug #21174: Index degrades sort performance and +# optimizer does not honor IGNORE INDEX +# +CREATE TABLE t1 (a INT, b INT, KEY(a)); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4); + +EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2; +EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2; + +DROP TABLE t1; diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 874f3cd1a80..5427727a8f4 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -746,3 +746,51 @@ EXPLAIN SELECT DISTINCT a,a FROM t1 ORDER BY a; SELECT DISTINCT a,a FROM t1 ORDER BY a; DROP TABLE t1; + +# +# Bug #21007: NATURAL JOIN (any JOIN (2 x NATURAL JOIN)) crashes the server +# + +CREATE TABLE t1 (id1 INT, id2 INT); +CREATE TABLE t2 (id2 INT, id3 INT, id5 INT); +CREATE TABLE t3 (id3 INT, id4 INT); +CREATE TABLE t4 (id4 INT); +CREATE TABLE t5 (id5 INT, id6 INT); +CREATE TABLE t6 (id6 INT); + +INSERT INTO t1 VALUES(1,1); +INSERT INTO t2 VALUES(1,1,1); +INSERT INTO t3 VALUES(1,1); +INSERT INTO t4 VALUES(1); +INSERT INTO t5 VALUES(1,1); +INSERT INTO t6 VALUES(1); + +-- original bug query +SELECT * FROM +t1 + NATURAL JOIN +(t2 JOIN (t3 NATURAL JOIN t4, t5 NATURAL JOIN t6) + ON (t3.id3 = t2.id3 AND t5.id5 = t2.id5)); + +-- inner join swapped +SELECT * FROM +t1 + NATURAL JOIN +(((t3 NATURAL JOIN t4) join (t5 NATURAL JOIN t6) on t3.id4 = t5.id5) JOIN t2 + ON (t3.id3 = t2.id3 AND t5.id5 = t2.id5)); + +-- one join less, no ON cond +SELECT * FROM t1 NATURAL JOIN ((t3 join (t5 NATURAL JOIN t6)) JOIN t2); + +-- wrong error message: 'id2' - ambiguous column +SELECT * FROM +(t2 JOIN (t3 NATURAL JOIN t4, t5 NATURAL JOIN t6) + ON (t3.id3 = t2.id3 AND t5.id5 = t2.id5)) + NATURAL JOIN +t1; +SELECT * FROM +(t2 JOIN ((t3 NATURAL JOIN t4) join (t5 NATURAL JOIN t6))) + NATURAL JOIN +t1; + +DROP TABLE t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index a7f1eeaa2cc..bf18b8da941 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -1,3 +1,4 @@ +-- source include/not_embedded.inc # # test of HANDLER ... # diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index fb715fccefe..03ba8661a3c 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -165,6 +165,26 @@ SELECT * from t1; DROP TABLE t1; # +# Bug #9719: problem with delete +# + +create table t1(a int not null, key using btree(a)) engine=heap; +insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3); +select a from t1 where a > 2 order by a; +delete from t1 where a < 4; +select a from t1 order by a; +insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3); +select a from t1 where a > 4 order by a; +delete from t1 where a > 4; +select a from t1 order by a; +select a from t1 where a > 3 order by a; +delete from t1 where a >= 2; +select a from t1 order by a; +drop table t1; + +--echo End of 4.1 tests + +# # BUG#18160 - Memory-/HEAP Table endless growing indexes # CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; @@ -184,4 +204,4 @@ CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY; INSERT INTO t1 VALUES(NULL),(NULL); DROP TABLE t1; -# End of 4.1 tests +--echo End of 5.0 tests diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest index 3afc36935f8..a07da161279 100644 --- a/mysql-test/t/im_daemon_life_cycle.imtest +++ b/mysql-test/t/im_daemon_life_cycle.imtest @@ -6,22 +6,7 @@ # ########################################################################### ---source include/im_check_os.inc - -########################################################################### - -# Wait for mysqld1 (guarded instance) to start. - ---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started - -# Let IM detect that mysqld1 is online. This delay should be longer than -# monitoring interval. - ---sleep 3 - -# Check that start conditions are as expected. - -SHOW INSTANCES; +--source include/im_check_env.inc ########################################################################### diff --git a/mysql-test/t/im_life_cycle.imtest b/mysql-test/t/im_life_cycle.imtest index 2cbe53a7b28..ddfb62d312e 100644 --- a/mysql-test/t/im_life_cycle.imtest +++ b/mysql-test/t/im_life_cycle.imtest @@ -6,34 +6,7 @@ # ########################################################################### ---source include/im_check_os.inc - -########################################################################### -# -# 1.1.1. Check that Instance Manager is able: -# - to read definitions of two mysqld-instances; -# - to start the first instance; -# - to understand 'nonguarded' option and keep the second instance down; -# -########################################################################### - ---echo ---echo -------------------------------------------------------------------- ---echo -- 1.1.1. ---echo -------------------------------------------------------------------- - -# Wait for mysqld1 (guarded instance) to start. - ---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started - -# Let IM detect that mysqld1 is online. This delay should be longer than -# monitoring interval. - ---sleep 3 - -# Check that start conditions are as expected. - -SHOW INSTANCES; +--source include/im_check_env.inc ########################################################################### # @@ -54,9 +27,10 @@ START INSTANCE mysqld2; # FIXME: START INSTANCE should be synchronous. --exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; --connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD2_PORT,$IM_MYSQLD2_SOCK) @@ -86,9 +60,10 @@ STOP INSTANCE mysqld2; # FIXME: STOP INSTANCE should be synchronous. --exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; ########################################################################### @@ -114,8 +89,8 @@ START INSTANCE mysqld1; ########################################################################### # -# 1.1.5. Check that Instance Manager reports correct errors for 'STOP INSTANCE' -# command: +# 1.1.5. Check that Instance Manager reports correct errors for +# 'STOP INSTANCE' command: # - if the client tries to start unregistered instance; # - if the client tries to start already stopped instance; # - if the client submits invalid arguments; @@ -146,12 +121,10 @@ STOP INSTANCE mysqld3; --echo -- 1.1.6. --echo -------------------------------------------------------------------- -SHOW INSTANCES; - --exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD1_PATH_PID restarted 30 -# Give some time to IM to detect that mysqld was restarted. It should be longer -# than monitoring interval. +# Give some time to IM to detect that mysqld was restarted. It should be +# longer than monitoring interval. --sleep 3 @@ -172,16 +145,18 @@ START INSTANCE mysqld2; # FIXME: START INSTANCE should be synchronous. --exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; --exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD2_PATH_PID killed 10 -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; ########################################################################### @@ -218,3 +193,11 @@ START INSTANCE mysqld1,mysqld2,mysqld3; --error ER_SYNTAX_ERROR STOP INSTANCE mysqld1,mysqld2,mysqld3; + +# +# Bug #12673: Instance Manager: allows to stop the instance many times +# +--error 3001 +STOP INSTANCE mysqld2; + +--echo End of 5.0 tests diff --git a/mysql-test/t/im_options_set.imtest b/mysql-test/t/im_options_set.imtest index a9b64861f99..6a70c31c0a4 100644 --- a/mysql-test/t/im_options_set.imtest +++ b/mysql-test/t/im_options_set.imtest @@ -38,33 +38,7 @@ ########################################################################### ---source include/im_check_os.inc - -########################################################################### -# -# 0. Check starting conditions. -# -########################################################################### - -# - check the configuration file; - ---exec grep server_id $MYSQLTEST_VARDIR/im.cnf ; - -# - check the running instances. - ---connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK) - ---connection mysql1_con - -SHOW VARIABLES LIKE 'server_id'; - ---connection default - -# - check the internal cache. -# TODO: we should check only server_id option here. - -# SHOW INSTANCE OPTIONS mysqld1; -# SHOW INSTANCE OPTIONS mysqld2; +--source include/im_check_env.inc ########################################################################### # diff --git a/mysql-test/t/im_options_unset.imtest b/mysql-test/t/im_options_unset.imtest index 40629805d45..074c9a3b869 100644 --- a/mysql-test/t/im_options_unset.imtest +++ b/mysql-test/t/im_options_unset.imtest @@ -45,33 +45,7 @@ ########################################################################### ---source include/im_check_os.inc - -########################################################################### -# -# 0. Check starting conditions. -# -########################################################################### - -# - check the configuration file; - ---exec grep server_id $MYSQLTEST_VARDIR/im.cnf ; - -# - check the running instances. - ---connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK) - ---connection mysql1_con - -SHOW VARIABLES LIKE 'server_id'; - ---connection default - -# - check the internal cache. -# TODO: we should check only server_id option here. - -# SHOW INSTANCE OPTIONS mysqld1; -# SHOW INSTANCE OPTIONS mysqld2; +--source include/im_check_env.inc ########################################################################### # diff --git a/mysql-test/t/im_utils.imtest b/mysql-test/t/im_utils.imtest index 47902eeba52..52878f6c2b5 100644 --- a/mysql-test/t/im_utils.imtest +++ b/mysql-test/t/im_utils.imtest @@ -6,37 +6,17 @@ # ########################################################################### ---source include/im_check_os.inc +--source include/im_check_env.inc ########################################################################### # -# Check starting conditions. This test case assumes that: -# - two mysqld-instances are registered; -# - the first instance is online; -# - the second instance is offline; +# Check 'SHOW INSTANCE OPTIONS' command. # - -# Wait for mysqld1 (guarded instance) to start. - ---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started - -# Let IM detect that mysqld1 is online. This delay should be longer than -# monitoring interval. - ---sleep 3 - -# Check that start conditions are as expected. - -SHOW INSTANCES; - -# -# Check 'SHOW INSTANCE OPTIONS' command: -# - check that options of both offline and online instances are accessible; -# - since configuration of an mysqld-instance contains directories, we should -# completely ignore the second column (values) in order to make the test -# case produce the same results on different installations; -# TODO: ignore values of only directory-specific options. +# Since configuration of an mysqld-instance contains directories, we should +# completely ignore the second column (values) in order to make the test +# case produce the same results on different installations; +# TODO: ignore values of only directory-specific options. # --replace_column 2 VALUE diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index a2e19112cf9..9e5dac8b853 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -887,4 +887,47 @@ DROP FUNCTION f1; DROP PROCEDURE p1; DROP USER mysql_bug20230@localhost; +# +# Bug#18925: subqueries with MIN/MAX functions on INFORMARTION_SCHEMA +# + +SELECT t.table_name, c1.column_name + FROM information_schema.tables t + INNER JOIN + information_schema.columns c1 + ON t.table_schema = c1.table_schema AND + t.table_name = c1.table_name + WHERE t.table_schema = 'information_schema' AND + c1.ordinal_position = + ( SELECT COALESCE(MIN(c2.ordinal_position),1) + FROM information_schema.columns c2 + WHERE c2.table_schema = t.table_schema AND + c2.table_name = t.table_name AND + c2.column_name LIKE '%SCHEMA%' + ); +SELECT t.table_name, c1.column_name + FROM information_schema.tables t + INNER JOIN + information_schema.columns c1 + ON t.table_schema = c1.table_schema AND + t.table_name = c1.table_name + WHERE t.table_schema = 'information_schema' AND + c1.ordinal_position = + ( SELECT COALESCE(MIN(c2.ordinal_position),1) + FROM information_schema.columns c2 + WHERE c2.table_schema = 'information_schema' AND + c2.table_name = t.table_name AND + c2.column_name LIKE '%SCHEMA%' + ); + +# +# Bug#21231: query with a simple non-correlated subquery over +# INFORMARTION_SCHEMA.TABLES +# + +SELECT MAX(table_name) FROM information_schema.tables; +SELECT table_name from information_schema.tables + WHERE table_name=(SELECT MAX(table_name) + FROM information_schema.tables); + # End of 5.0 tests. diff --git a/mysql-test/t/information_schema_db.test b/mysql-test/t/information_schema_db.test index 2cfa766d799..4dfe1ad56b5 100644 --- a/mysql-test/t/information_schema_db.test +++ b/mysql-test/t/information_schema_db.test @@ -98,3 +98,60 @@ where table_schema='test'; drop function f1; drop function f2; drop view v1, v2; + +# +# Bug#20543: select on information_schema strange warnings, view, different +# schemas/users +# +# +create database testdb_1; +create user testdb_1@localhost; +grant all on testdb_1.* to testdb_1@localhost with grant option; + +create user testdb_2@localhost; +grant all on test.* to testdb_2@localhost with grant option; + +connect (testdb_1,localhost,testdb_1,,test); +use testdb_1; +create table t1 (f1 char(4)); +create view v1 as select f1 from t1; +grant insert on v1 to testdb_2@localhost; + +create table t3 (f1 char(4), f2 char(4)); +create view v3 as select f1,f2 from t3; +grant insert(f1), insert(f2) on v3 to testdb_2@localhost; + +connect (testdb_2,localhost,testdb_2,,test); +create view v2 as select f1 from testdb_1.v1; +create view v4 as select f1,f2 from testdb_1.v3; + +connection testdb_1; +revoke insert(f1) on v3 from testdb_2@localhost; +connection testdb_2; + +--error 1345 +show create view v4; +--error 1345 +show fields from v4; + +show fields from v2; +show fields from testdb_1.v1; +show create view v2; +--error 1142 +show create view testdb_1.v1; + +select table_name from information_schema.columns a +where a.table_name = 'v2'; +select view_definition from information_schema.views a +where a.table_name = 'v2'; +select view_definition from information_schema.views a +where a.table_name = 'testdb_1.v1'; + +--error 1356 +select * from v2; + +connection default; +drop view testdb_1.v1,v2, testdb_1.v3, v4; +drop database testdb_1; +drop user testdb_1@localhost; +drop user testdb_2@localhost; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 71b178d0e57..0c083ccdfd3 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1079,7 +1079,7 @@ drop table t1,t2,t3; # create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb; insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt'); -select name2 from t1 union all select name from t1 union all select id from t1; +select trim(name2) from t1 union all select trim(name) from t1 union all select trim(id) from t1; drop table t1; # diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 4b512ccce1d..59dbe5e96d4 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -90,6 +90,33 @@ SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2) ORDER BY t1.b LIMIT 5; DROP TABLE t1, t2, t3; + + +# BUG#21077 (The testcase is not deterministic so correct execution doesn't +# prove anything) For proof one should track if sequence of ha_innodb::* func +# calls is correct. +CREATE TABLE `t1` (`id1` INT) ; +INSERT INTO `t1` (`id1`) VALUES (1),(5),(2); + +CREATE TABLE `t2` ( + `id1` INT, + `id2` INT NOT NULL, + `id3` INT, + `id4` INT NOT NULL, + UNIQUE (`id2`,`id4`), + KEY (`id1`) +) ENGINE=InnoDB; + +INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES +(1,1,1,0), +(1,1,2,1), +(5,1,2,2), +(6,1,2,3), +(1,2,2,2), +(1,2,1,1); + +SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = 1 AND `id3` = 2); +DROP TABLE t1, t2; # # Bug #12882 min/max inconsistent on empty table # @@ -255,3 +282,23 @@ explain select distinct f1 a, f1 b from t1; explain select distinct f1, f2 from t1; drop table t1; +# +# Test for bug #17164: ORed FALSE blocked conversion of outer join into join +# + +CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), + INDEX (name)) ENGINE=InnoDB; +CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), + FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); +INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); + +EXPLAIN +SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id + WHERE t1.name LIKE 'A%'; + +EXPLAIN +SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id + WHERE t1.name LIKE 'A%' OR FALSE; + +DROP TABLE t1,t2; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index b6b94d07e87..6f86ed897ac 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -249,6 +249,24 @@ INSERT INTO t3 (SELECT x, y FROM t1 JOIN t2 USING (y) WHERE z = 1); DROP TABLE IF EXISTS t1,t2,t3; # +# Bug #21774: Column count doesn't match value count at row x +# +CREATE DATABASE bug21774_1; +CREATE DATABASE bug21774_2; + +CREATE TABLE bug21774_1.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_2.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_1.t2(id VARCHAR(10) NOT NULL,label VARCHAR(255)); + +INSERT INTO bug21774_2.t1 SELECT t1.* FROM bug21774_1.t1; + +use bug21774_1; +INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1; + +DROP DATABASE bug21774_1; +DROP DATABASE bug21774_2; + +# # Bug #20989: View '(null).(null)' references invalid table(s)... on # SQL SECURITY INVOKER # diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index dc4e240750c..20462f2ca3f 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -760,27 +760,6 @@ EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b DROP TABLE t1,t2; # -# Test for bug #17164: ORed FALSE blocked conversion of outer join into join -# - -CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), - INDEX (name)) ENGINE=InnoDB; -CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), - FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB; -INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); -INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); - -EXPLAIN -SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id - WHERE t1.name LIKE 'A%'; - -EXPLAIN -SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id - WHERE t1.name LIKE 'A%' OR FALSE; - -DROP TABLE t1,t2; - -# # Bug 19396: LEFT OUTER JOIN over views in curly braces # --disable_warnings diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test index 6df865278f6..cf7789428b2 100644 --- a/mysql-test/t/limit.test +++ b/mysql-test/t/limit.test @@ -60,4 +60,14 @@ select 1 as a from t1 union all select 1 from dual limit 1; (select 1 as a from t1) union all (select 1 from dual) limit 1; drop table t1; +# +# Bug #21787: COUNT(*) + ORDER BY + LIMIT returns wrong result +# +create table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6),(7); +explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; +select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3; + # End of 4.1 tests diff --git a/mysql-test/t/loaddata_autocom_innodb.test b/mysql-test/t/loaddata_autocom_innodb.test new file mode 100644 index 00000000000..d7f152cb286 --- /dev/null +++ b/mysql-test/t/loaddata_autocom_innodb.test @@ -0,0 +1,4 @@ +--source include/have_innodb.inc +let $engine_type= InnoDB; + +--source include/loaddata_autocom.inc diff --git a/mysql-test/t/loaddata_autocom_ndb.test b/mysql-test/t/loaddata_autocom_ndb.test new file mode 100644 index 00000000000..f4a6743aabe --- /dev/null +++ b/mysql-test/t/loaddata_autocom_ndb.test @@ -0,0 +1,4 @@ +--source include/have_ndb.inc +let $engine_type=ndbcluster; + +--source include/loaddata_autocom.inc diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 98fadcfc75d..9e3eabf474b 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -52,8 +52,8 @@ drop table t1; --exec $MYSQL --default-character-set=cp932 test -e "charset utf8;" # its usage to switch internally in mysql to requested charset ---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set @@session.character_set_client= cp932; select 'ƒ\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('ƒ\'); select * from t1; drop table t1;" ---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set character_set_client= cp932; select 'ƒ\'" +--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select 'ƒ\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('ƒ\'); select * from t1; drop table t1;" +--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select 'ƒ\'" --exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select 'ƒ\'" --exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select 'ƒ\'" @@ -70,13 +70,81 @@ drop table t1; # # "DESCRIBE" commands may return strange NULLness flags. # +--exec $MYSQL --default-character-set utf8 test -e "create table t1 (i int, j int not null, k int); insert into t1 values (null, 1, null); select * from t1; describe t1; drop table t1;" --exec $MYSQL -t --default-character-set utf8 test -e "create table t1 (i int, j int not null, k int); insert into t1 values (null, 1, null); select * from t1; describe t1; drop table t1;" # # Bug#19564: mysql displays NULL instead of space # +--exec $MYSQL test -e "create table b19564 (i int, s1 char(1)); insert into b19564 values (1, 'x'); insert into b19564 values (2, NULL); insert into b19564 values (3, ' '); select * from b19564 order by i; drop table b19564;" --exec $MYSQL -t test -e "create table b19564 (i int, s1 char(1)); insert into b19564 values (1, 'x'); insert into b19564 values (2, NULL); insert into b19564 values (3, ' '); select * from b19564 order by i; drop table b19564;" ---echo End of 5.0 tests +# +# Bug#21618: NULL shown as empty string in client +# +--exec $MYSQL test -e "select unhex('zz');" +--exec $MYSQL -t test -e "select unhex('zz');" + +# Bug#19265 describe command does not work from mysql prompt +# + +create table t1(a int, b varchar(255), c int); +--exec $MYSQL test -e "desc t1" +--exec $MYSQL test -e "desc t1\g" +drop table t1; +--disable_parsing +# +# Bug#21042 mysql client segfaults on importing a mysqldump export +# +--error 1 +--exec $MYSQL test -e "connect verylongdatabasenamethatshouldblowthe256byteslongbufferincom_connectfunctionxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxendcccccccdxxxxxxxxxxxxxxxxxkskskskskkskskskskskskskskskskkskskskskkskskskskskskskskskend" 2>&1 +--enable_parsing + + +# +# Bug #20432: mysql client interprets commands in comments +# +# if the client sees the 'use' within the comment, we haven't fixed +--exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "*/" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 + +# SQL can have embedded comments => workie +--exec echo "select /*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "*/ 1" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 + +# client commands on the other hand must be at BOL => error +--exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "xxx" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec echo "*/ use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql +--error 1 +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 + +# client comment recognized, but parameter missing => error +--exec echo "use" > $MYSQLTEST_VARDIR/tmp/bug20432.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 + +# +# Bug #20328: mysql client interprets commands in comments +# +--exec $MYSQL -e 'help' > $MYSQLTEST_VARDIR/tmp/bug20328_1.result +--exec $MYSQL -e 'help ' > $MYSQLTEST_VARDIR/tmp/bug20328_2.result +--exec diff $MYSQLTEST_VARDIR/tmp/bug20328_1.result $MYSQLTEST_VARDIR/tmp/bug20328_2.result + +# +# Bug #20103: Escaping with backslash does not work +# +--exec echo "SET SQL_MODE = 'NO_BACKSLASH_ESCAPES';" > $MYSQLTEST_VARDIR/tmp/bug20103.sql +--exec echo "SELECT '\';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 + +--exec echo "SET SQL_MODE = '';" > $MYSQLTEST_VARDIR/tmp/bug20103.sql +--exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 + +--echo End of 5.0 tests diff --git a/mysql-test/t/mysql_client.test b/mysql-test/t/mysql_client.test deleted file mode 100644 index e4b6658b631..00000000000 --- a/mysql-test/t/mysql_client.test +++ /dev/null @@ -1,29 +0,0 @@ -# This test should work in embedded server after we fix mysqltest --- source include/not_embedded.inc - -# -# Bug #20432: mysql client interprets commands in comments -# - -# if the client sees the 'use' within the comment, we haven't fixed ---exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "*/" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 - -# SQL can have embedded comments => workie ---exec echo "select /*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "*/ 1" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 - -# client commands on the other hand must be at BOL => error ---exec echo "/*" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "xxx" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec echo "*/ use" >> $MYSQLTEST_VARDIR/tmp/bug20432.sql ---error 1 ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 - -# client comment recognized, but parameter missing => error ---exec echo "use" > $MYSQLTEST_VARDIR/tmp/bug20432.sql ---exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index b61deeac001..66a27abd61a 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -8,8 +8,8 @@ # server or run mysql-test-run --debug mysql_client_test and check # var/log/mysql_client_test.trace ---disable_result_log ---exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M +--exec echo "$MYSQL_CLIENT_TEST" > $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1 +--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1 # End of 4.1 tests echo ok; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index bc88be001ab..338e16363ea 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -9,3 +9,17 @@ --replace_result 'Table is already up to date' OK --exec $MYSQL_CHECK --analyze --optimize --databases test information_schema mysql --exec $MYSQL_CHECK --analyze --optimize information_schema schemata + +# +# Bug #16502: mysqlcheck tries to check views +# +create table t1 (a int); +create view v1 as select * from t1; +--replace_result 'Table is already up to date' OK +--exec $MYSQL_CHECK --analyze --optimize --databases test +--replace_result 'Table is already up to date' OK +--exec $MYSQL_CHECK --all-in-1 --analyze --optimize --databases test +drop view v1; +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 9508846f71a..7c4962e4dab 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -548,71 +548,6 @@ INSERT INTO t1 VALUES (1),(2),(3); --exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test DROP TABLE t1; - -# -# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) -# - -create database db1; -use db1; - -CREATE TABLE t2 ( - a varchar(30) default NULL, - KEY a (a(5)) -); - -INSERT INTO t2 VALUES ('alfred'); -INSERT INTO t2 VALUES ('angie'); -INSERT INTO t2 VALUES ('bingo'); -INSERT INTO t2 VALUES ('waffle'); -INSERT INTO t2 VALUES ('lemon'); -create view v2 as select * from t2 where a like 'a%' with check option; ---exec $MYSQL_DUMP --skip-comments db1 -drop table t2; -drop view v2; -drop database db1; - -# -# Bug 10713 mysqldump includes database in create view and referenced tables -# - -# create table and views in db2 -create database db2; -use db2; -create table t1 (a int); -create table t2 (a int, b varchar(10), primary key(a)); -insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg"); -insert into t1 values (289), (298), (234), (456), (789); -create view v1 as select * from t2; -create view v2 as select * from t1; - -# dump tables and view from db2 ---exec $MYSQL_DUMP db2 > $MYSQLTEST_VARDIR/tmp/bug10713.sql - -# drop the db, tables and views -drop table t1, t2; -drop view v1, v2; -drop database db2; - -# create db1 and reload dump -create database db1; -use db1; ---exec $MYSQL db1 < $MYSQLTEST_VARDIR/tmp/bug10713.sql - -# check that all tables and views could be created -show tables; -select * from t2 order by a; - -drop table t1, t2; -drop database db1; - -# -# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence -# - ---exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump - - # # Bug #9558 mysqldump --no-data db t1 t2 format still dumps data # @@ -720,6 +655,12 @@ select * from t1; drop table t1; # +# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence +# + +--exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump + +# # BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]" # create table `t1` ( @@ -748,9 +689,88 @@ show create table `t1`; drop table `t1`; +# +# Bug #18536: wrong table order +# + +create table t1(a int); +create table t2(a int); +create table t3(a int); +--error 6 +--exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2 +drop table t1, t2, t3; + +# +# Bug #21288: mysqldump segmentation fault when using --where +# +create table t1 (a int); +--error 2 +--exec $MYSQL_DUMP --skip-comments --force test t1 --where='xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 2>&1 +drop table t1; + --echo End of 4.1 tests # +# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# + +create database db1; +use db1; + +CREATE TABLE t2 ( + a varchar(30) default NULL, + KEY a (a(5)) +); + +INSERT INTO t2 VALUES ('alfred'); +INSERT INTO t2 VALUES ('angie'); +INSERT INTO t2 VALUES ('bingo'); +INSERT INTO t2 VALUES ('waffle'); +INSERT INTO t2 VALUES ('lemon'); +create view v2 as select * from t2 where a like 'a%' with check option; +--exec $MYSQL_DUMP --skip-comments db1 +drop table t2; +drop view v2; +drop database db1; +use test; + +# +# Bug 10713 mysqldump includes database in create view and referenced tables +# + +# create table and views in db2 +create database db2; +use db2; +create table t1 (a int); +create table t2 (a int, b varchar(10), primary key(a)); +insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg"); +insert into t1 values (289), (298), (234), (456), (789); +create view v1 as select * from t2; +create view v2 as select * from t1; + +# dump tables and view from db2 +--exec $MYSQL_DUMP db2 > $MYSQLTEST_VARDIR/tmp/bug10713.sql + +# drop the db, tables and views +drop table t1, t2; +drop view v1, v2; +drop database db2; +use test; + +# create db1 and reload dump +create database db1; +use db1; +--exec $MYSQL db1 < $MYSQLTEST_VARDIR/tmp/bug10713.sql + +# check that all tables and views could be created +show tables; +select * from t2 order by a; + +drop table t1, t2; +drop database db1; +use test; + +# # dump of view # create table t1(a int); @@ -813,6 +833,7 @@ select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; drop view v1, v2, v3; drop table t1; + # # Test for dumping triggers # @@ -1073,19 +1094,6 @@ insert into t1 values ('',''); drop table t1; # -# Bug #18536: wrong table order -# - -create table t1(a int); -create table t2(a int); -create table t3(a int); ---error 6 ---exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2 -drop table t1, t2, t3; - ---echo End of 4.1 tests - -# # Bug 14871 Invalid view dump output # @@ -1266,3 +1274,110 @@ use mysqldump_dbb; drop view v1; drop table t1; drop database mysqldump_dbb; +use test; + +# +# Bug#21215 mysqldump creating incomplete backups without warning +# + +# Create user without sufficient privs to perform the requested operation +create user mysqltest_1@localhost; +create table t1(a int, b varchar(34)); + +# To get consistent output, reset the master, starts over from first log +reset master; + +# Execute mysqldump, will fail on FLUSH TABLES +--error 2 +--exec $MYSQL_DUMP --compact --master-data -u mysqltest_1 test 2>&1 + +# Execute mysqldump, will fail on FLUSH TABLES +# use --force, should no affect behaviour +--error 2 +--exec $MYSQL_DUMP --compact --force --master-data -u mysqltest_1 test 2>&1 + +# Add RELOAD grants +grant RELOAD on *.* to mysqltest_1@localhost; + +# Execute mysqldump, will fail on SHOW MASTER STATUS +--error 2 +--exec $MYSQL_DUMP --compact --master-data -u mysqltest_1 test 2>&1 + +# Execute mysqldump, will fail on SHOW MASTER STATUS. +# use --force, should not alter behaviour +--error 2 +--exec $MYSQL_DUMP --compact --force --master-data -u mysqltest_1 test 2>&1 + +# Add REPLICATION CLIENT grants +grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; + +# Execute mysqldump, should now succeed +--exec $MYSQL_DUMP --compact --master-data -u mysqltest_1 test 2>&1 + +# Clean up +drop table t1; +drop user mysqltest_1@localhost; + +# +# Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the +# information_schema database. +# +# Bug #21424 mysqldump failing to export/import views +# + +# Do as root +connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); +connection root; +create database mysqldump_myDB; +use mysqldump_myDB; +create user myDB_User; +grant create, create view, select, insert on mysqldump_myDB.* to myDB_User@localhost; +create table t1 (c1 int); +insert into t1 values (3); + +# Do as a user +connect (user1,localhost,myDB_User,,mysqldump_myDB,$MASTER_MYPORT,$MASTER_MYSOCK); +connection user1; +use mysqldump_myDB; +create table u1 (f1 int); +insert into u1 values (4); +create view v1 (c1) as select * from t1; + +# Backup should not fail for Bug #21527. Flush priviliges test begins. +--exec $MYSQL_DUMP --skip-comments --add-drop-table --flush-privileges --ignore-table=mysql.general_log --ignore-table=mysql.slow_log --databases mysqldump_myDB mysql > $MYSQLTEST_VARDIR/tmp/bug21527.sql + +# Clean up +connection root; +use mysqldump_myDB; +drop view v1; +drop table t1; +drop table u1; +revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; +drop user myDB_User; +drop database mysqldump_myDB; +flush privileges; + +# Bug #21424 continues from here. +# Restore. Flush Privileges test ends. +--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21527.sql; + +# Do as a user +connection user1; +use mysqldump_myDB; + +# Ultimate test for correct data. +select * from mysqldump_myDB.v1; +select * from mysqldump_myDB.u1; + +#Final cleanup. +connection root; +use mysqldump_myDB; +drop view v1; +drop table t1; +drop table u1; +revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; +drop user myDB_User; +drop database mysqldump_myDB; +use test; + +--echo End of 5.0 tests diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 78c4ae2b531..9ed93079f57 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -25,3 +25,12 @@ select "---- -v -t ---------" as ""; select "---- -v -v -t ------" as ""; --exec $MYSQL_SHOW test -v -v -t DROP TABLE t1, t2; + +# +# Bug #19147: mysqlshow INFORMATION_SCHEMA does not work +# +--exec $MYSQL_SHOW information_schema +--exec $MYSQL_SHOW INFORMATION_SCHEMA +--exec $MYSQL_SHOW inf_rmation_schema + +--echo End of 5.0 tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 3968eb519e1..6a0b805f43b 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1125,3 +1125,18 @@ drop table t1; drop table t1; +# +# Bug#19890 mysqltest: "query" command is broken +# + +# It should be possible to use the command "query" to force mysqltest to +# send the command to the server although it's a builtin mysqltest command. +--error 1064 +query sleep; + +--error 1064 +--query sleep + +# Just an empty query command +--error 1065 +query ; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 5d79d5eb9f9..6c1a4e44f4b 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -700,3 +700,13 @@ select * from t1 order by f1; select * from t1 order by f2; select * from t1 order by f3; drop table t1; + +# +# Bug#16561 Unknown ERROR msg "ERROR 1186 (HY000): Binlog closed" by perror +# + +# As long there is no error code 1186 defined by NDB +# we should get a message "Illegal ndb error code: 1186" +--error 1 +--exec $MY_PERROR --ndb 1186 2>&1 + diff --git a/mysql-test/t/ndb_lock.test b/mysql-test/t/ndb_lock.test index 54214ee72ec..48a8b77dcd7 100644 --- a/mysql-test/t/ndb_lock.test +++ b/mysql-test/t/ndb_lock.test @@ -73,7 +73,7 @@ drop table t1; create table t1 (x integer not null primary key, y varchar(32), z integer, key(z)) engine = ndb; -insert into t1 values (1,'one',1), (2,'two',2),(3,"three",3); +insert into t1 values (1,'one',1); # PK access connection con1; @@ -82,12 +82,23 @@ select * from t1 where x = 1 for update; connection con2; begin; -select * from t1 where x = 2 for update; --error 1205 select * from t1 where x = 1 for update; rollback; connection con1; +rollback; +insert into t1 values (2,'two',2),(3,"three",3); +begin; +select * from t1 where x = 1 for update; + +connection con2; +--error 1205 +select * from t1 where x = 1 for update; +select * from t1 where x = 2 for update; +rollback; + +connection con1; commit; # table scan diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index afee381f5b7..49f8fc4d7d4 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -10,14 +10,18 @@ insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/L=Uppsala/O=MySQL AB/CN=MySQL Client/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/emailAddress=abstract.mysql.developer@mysql.com"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; connect (con1,localhost,ssl_user1,,,,,SSL); connect (con2,localhost,ssl_user2,,,,,SSL); connect (con3,localhost,ssl_user3,,,,,SSL); connect (con4,localhost,ssl_user4,,,,,SSL); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (con5,localhost,ssl_user5,,,,,SSL); connection con1; # Check ssl turned on @@ -49,7 +53,7 @@ delete from t1; connection default; drop user ssl_user1@localhost, ssl_user2@localhost, -ssl_user3@localhost, ssl_user4@localhost; +ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 98e542dac95..1104c859ab8 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -578,3 +578,35 @@ INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10); DROP TABLE t1; # End of 4.1 tests + +# +# Bug#21302: Result not properly sorted when using an ORDER BY on a second +# table in a join +# +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); + +explain SELECT t1.b as a, t2.b as c FROM + t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; +SELECT t2.b as c FROM + t1 LEFT JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; + +# check that it still removes sort of const table +explain SELECT t1.b as a, t2.b as c FROM + t1 JOIN t1 t2 ON (t1.a = t2.a AND t2.a = 2) +ORDER BY c; + +CREATE TABLE t2 LIKE t1; +INSERT INTO t2 SELECT * from t1; +CREATE TABLE t3 LIKE t1; +INSERT INTO t3 SELECT * from t1; +CREATE TABLE t4 LIKE t1; +INSERT INTO t4 SELECT * from t1; +INSERT INTO t1 values (0,0),(4,4); + +SELECT t2.b FROM t1 LEFT JOIN (t2, t3 LEFT JOIN t4 ON t3.a=t4.a) +ON (t1.a=t2.a AND t1.b=t3.b) order by t2.b; + +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/t/perror.test b/mysql-test/t/perror.test new file mode 100644 index 00000000000..a4b99d8aa22 --- /dev/null +++ b/mysql-test/t/perror.test @@ -0,0 +1,19 @@ +# +# Check if the variable MY_PERROR is set +# +--require r/have_perror.require +disable_query_log; +eval select LENGTH("$MY_PERROR") > 0 as "have_perror"; +enable_query_log; + +--exec $MY_PERROR 150 > /dev/null +--exec $MY_PERROR --silent 120 > /dev/null + +# +# Bug#16561 Unknown ERROR msg "ERROR 1186 (HY000): Binlog closed" by perror +# + +# Test with error code 10000 as it's a common "unknown error" +# As there is no error code defined for 10000, expect error +--error 1 +--exec $MY_PERROR 10000 2>&1 diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 8eb383de57a..5b2e37ecc94 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -491,6 +491,7 @@ deallocate prepare stmt; drop table t1, t2; # +# # Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating # tables" # Check that multi-delete tables are also cleaned up before re-execution. @@ -538,86 +539,6 @@ SELECT FOUND_ROWS(); deallocate prepare stmt; # -# Bug#8115: equality propagation and prepared statements -# - -create table t1 (a char(3) not null, b char(3) not null, - c char(3) not null, primary key (a, b, c)); -create table t2 like t1; - -# reduced query -prepare stmt from - "select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) - where t1.a=1"; -execute stmt; -execute stmt; -execute stmt; - -# original query -prepare stmt from -"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from -(t1 left outer join t2 on t2.a=? and t1.b=t2.b) -left outer join t2 t3 on t3.a=? where t1.a=?"; - -set @a:=1, @b:=1, @c:=1; - -execute stmt using @a, @b, @c; -execute stmt using @a, @b, @c; -execute stmt using @a, @b, @c; - -deallocate prepare stmt; - -drop table t1,t2; - - -# -# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement -# - -eval SET @aux= "SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS A, - INFORMATION_SCHEMA.COLUMNS B - WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA - AND A.TABLE_NAME = B.TABLE_NAME - AND A.COLUMN_NAME = B.COLUMN_NAME AND - A.TABLE_NAME = 'user'"; - -let $exec_loop_count= 3; -eval prepare my_stmt from @aux; -while ($exec_loop_count) -{ - eval execute my_stmt; - dec $exec_loop_count; -} -deallocate prepare my_stmt; - -# Test CALL in prepared mode -delimiter |; ---disable_warnings -drop procedure if exists p1| -drop table if exists t1| ---enable_warnings -create table t1 (id int)| -insert into t1 values(1)| -create procedure p1(a int, b int) -begin - declare c int; - select max(id)+1 into c from t1; - insert into t1 select a+b; - insert into t1 select a-b; - insert into t1 select a-c; -end| -set @a= 3, @b= 4| -prepare stmt from "call p1(?, ?)"| -execute stmt using @a, @b| -execute stmt using @a, @b| -select * from t1| -deallocate prepare stmt| -drop procedure p1| -drop table t1| -delimiter ;| - -# # Bug#9096 "select doesn't return all matched records if prepared statements # is used" # The bug was is bad co-operation of the optimizer's algorithm which determines @@ -692,35 +613,6 @@ deallocate prepare stmt; drop table t1, t2; # -# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement -# support for placeholders in LIMIT clause." -# Add basic test coverage for the feature. -# -create table t1 (a int); -insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -prepare stmt from "select * from t1 limit ?, ?"; -set @offset=0, @limit=1; -execute stmt using @offset, @limit; -select * from t1 limit 0, 1; -set @offset=3, @limit=2; -execute stmt using @offset, @limit; -select * from t1 limit 3, 2; -prepare stmt from "select * from t1 limit ?"; -execute stmt using @limit; ---error 1235 -prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; -prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; -set @offset=9; -set @limit=2; -execute stmt using @offset, @limit; -prepare stmt from "(select * from t1 limit ?, ?) union all - (select * from t1 limit ?, ?) order by a limit ?"; -execute stmt using @offset, @limit, @offset, @limit, @limit; - -drop table t1; -deallocate prepare stmt; - -# # Bug#11060 "Server crashes on calling stored procedure with INSERT SELECT # UNION SELECT" aka "Server crashes on re-execution of prepared INSERT ... # SELECT with UNION". @@ -837,22 +729,6 @@ select ??; select ? from t1; --enable_ps_protocol drop table t1; - -# -# Bug#12651 -# (Crash on a PS including a subquery which is a select from a simple view) -# -CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; -CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; -CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; - -PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; -EXECUTE b12651; - -DROP VIEW b12651_V1; -DROP TABLE b12651_T1, b12651_T2; -DEALLOCATE PREPARE b12651; - # # Bug#9359 "Prepared statements take snapshot of system vars at PREPARE # time" @@ -1087,7 +963,172 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count; set global max_prepared_stmt_count= @old_max_prepared_stmt_count; --enable_ps_protocol -# End of 4.1 tests +# +# Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating +# tables" +# Check that multi-delete tables are also cleaned up before re-execution. +# +--disable_warnings +drop table if exists t1; +create temporary table if not exists t1 (a1 int); +--enable_warnings +# exact delete syntax is essential +prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1"; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +# the server crashed on the next statement without the fix +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +# the problem was in memory corruption: repeat the test just in case +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +deallocate prepare stmt; + +--echo End of 4.1 tests +############################# 5.0 tests start ################################ +# +# +# Bug#6102 "Server crash with prepared statement and blank after +# function name" +# ensure that stored functions are cached when preparing a statement +# before we open tables +# +create table t1 (a varchar(20)); +insert into t1 values ('foo'); +--error 1305 +prepare stmt FROM 'SELECT char_length (a) FROM t1'; +drop table t1; + +# +# Bug#8115: equality propagation and prepared statements +# + +create table t1 (a char(3) not null, b char(3) not null, + c char(3) not null, primary key (a, b, c)); +create table t2 like t1; + +# reduced query +prepare stmt from + "select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) + where t1.a=1"; +execute stmt; +execute stmt; +execute stmt; + +# original query +prepare stmt from +"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from +(t1 left outer join t2 on t2.a=? and t1.b=t2.b) +left outer join t2 t3 on t3.a=? where t1.a=?"; + +set @a:=1, @b:=1, @c:=1; + +execute stmt using @a, @b, @c; +execute stmt using @a, @b, @c; +execute stmt using @a, @b, @c; + +deallocate prepare stmt; + +drop table t1,t2; + + +# +# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement +# + +eval SET @aux= "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS A, + INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME + AND A.COLUMN_NAME = B.COLUMN_NAME AND + A.TABLE_NAME = 'user'"; + +let $exec_loop_count= 3; +eval prepare my_stmt from @aux; +while ($exec_loop_count) +{ + eval execute my_stmt; + dec $exec_loop_count; +} +deallocate prepare my_stmt; + +# Test CALL in prepared mode +delimiter |; +--disable_warnings +drop procedure if exists p1| +drop table if exists t1| +--enable_warnings +create table t1 (id int)| +insert into t1 values(1)| +create procedure p1(a int, b int) +begin + declare c int; + select max(id)+1 into c from t1; + insert into t1 select a+b; + insert into t1 select a-b; + insert into t1 select a-c; +end| +set @a= 3, @b= 4| +prepare stmt from "call p1(?, ?)"| +execute stmt using @a, @b| +execute stmt using @a, @b| +select * from t1| +deallocate prepare stmt| +drop procedure p1| +drop table t1| +delimiter ;| + + +# +# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement +# support for placeholders in LIMIT clause." +# Add basic test coverage for the feature. +# +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +prepare stmt from "select * from t1 limit ?, ?"; +set @offset=0, @limit=1; +execute stmt using @offset, @limit; +select * from t1 limit 0, 1; +set @offset=3, @limit=2; +execute stmt using @offset, @limit; +select * from t1 limit 3, 2; +prepare stmt from "select * from t1 limit ?"; +execute stmt using @limit; +--error 1235 +prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; +prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; +set @offset=9; +set @limit=2; +execute stmt using @offset, @limit; +prepare stmt from "(select * from t1 limit ?, ?) union all + (select * from t1 limit ?, ?) order by a limit ?"; +execute stmt using @offset, @limit, @offset, @limit, @limit; + +drop table t1; +deallocate prepare stmt; + +# +# Bug#12651 +# (Crash on a PS including a subquery which is a select from a simple view) +# +CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; +CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; +CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; + +PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; +EXECUTE b12651; + +DROP VIEW b12651_V1; +DROP TABLE b12651_T1, b12651_T2; +DEALLOCATE PREPARE b12651; + + # # Bug #14956: ROW_COUNT() returns incorrect result after EXECUTE of prepared @@ -1288,4 +1329,33 @@ create temporary table t1 (i int); # Restore the old environemnt # use test; -# End of 5.0 tests + + +# +# BUG#21166: Prepared statement causes signal 11 on second execution +# +# Changes in an item tree done by optimizer weren't properly +# registered and went unnoticed, which resulted in preliminary freeing +# of used memory. +# +--disable_warnings +DROP TABLE IF EXISTS t1, t2, t3; +--enable_warnings + +CREATE TABLE t1 (i BIGINT, j BIGINT); +CREATE TABLE t2 (i BIGINT); +CREATE TABLE t3 (i BIGINT, j BIGINT); + +PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i) + LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j)) + WHERE t1.i = ?"; + +SET @a= 1; +EXECUTE stmt USING @a; +EXECUTE stmt USING @a; + +DEALLOCATE PREPARE stmt; +DROP TABLE IF EXISTS t1, t2, t3; + + +--echo End of 5.0 tests. diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 72b69fc8d9f..8d0f9885e80 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -316,6 +316,7 @@ prepare stmt4 from ' show table status from test like ''t9%'' '; --replace_column 8 # 12 # 13 # 14 # # Bug#4288 execute stmt4; +--replace_column 2 # prepare stmt4 from ' show status like ''Threads_running'' '; execute stmt4; prepare stmt4 from ' show variables like ''sql_mode'' '; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index d53b05b98b1..240851e6ac4 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -656,3 +656,87 @@ explain select * from t1 where a not between 'b' and 'b'; select a, hex(filler) from t1 where a not between 'b' and 'b'; drop table t1,t2,t3; + +# +# BUG#21282 +# +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, key(a)); +insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C; + +set @a="select * from t2 force index (a) where a NOT IN(0"; +select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z; +set @a=concat(@a, ')'); + +insert into t2 values (11),(13),(15); + +set @b= concat("explain ", @a); + +prepare stmt1 from @b; +execute stmt1; + +prepare stmt1 from @a; +execute stmt1; + +drop table t1, t2; + +# +# Bug #18165: range access for BETWEEN with a constant for the first argument +# + +CREATE TABLE t1 ( + id int NOT NULL DEFAULT '0', + b int NOT NULL DEFAULT '0', + c int NOT NULL DEFAULT '0', + INDEX idx1(b,c), INDEX idx2(c)); + +INSERT INTO t1(id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); + +INSERT INTO t1(b,c) VALUES (3,4), (3,4); + +SELECT * FROM t1 WHERE b<=3 AND 3<=c; +SELECT * FROM t1 WHERE 3 BETWEEN b AND c; + +EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c; +EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c; + +SELECT * FROM t1 WHERE 0 < b OR 0 > c; +SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; + +EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c; +EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c; + +DROP TABLE t1; + +# +# Bug #16249: different results for a range with an without index +# when a range condition use an invalid datetime constant +# + +CREATE TABLE t1 ( + item char(20) NOT NULL default '', + started datetime NOT NULL default '0000-00-00 00:00:00', + price decimal(16,3) NOT NULL default '0.000', + PRIMARY KEY (item,started) +) ENGINE=MyISAM; + +INSERT INTO t1 VALUES +('A1','2005-11-01 08:00:00',1000), +('A1','2005-11-15 00:00:00',2000), +('A1','2005-12-12 08:00:00',3000), +('A2','2005-12-01 08:00:00',1000); + +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; + +DROP INDEX `PRIMARY` ON t1; + +EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00'; +SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00'; + +DROP TABLE t1; + +# End of 5.0 tests diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test index 16e1d76d460..91a7442226a 100644 --- a/mysql-test/t/repair.test +++ b/mysql-test/t/repair.test @@ -34,4 +34,15 @@ repair table t1; repair table t1 use_frm; drop table t1; +# +# BUG#18874 - Setting myisam_repair_threads > 1, index cardinality always 1 +# +CREATE TABLE t1(a INT, KEY(a)); +INSERT INTO t1 VALUES(1),(2),(3),(4),(5); +SET myisam_repair_threads=2; +REPAIR TABLE t1; +SHOW INDEX FROM t1; +SET myisam_repair_threads=@@global.myisam_repair_threads; +DROP TABLE t1; + # End of 4.1 tests diff --git a/mysql-test/t/rpl_ndb_innodb_trans-slave.opt b/mysql-test/t/rpl_ndb_innodb_trans-slave.opt new file mode 100644 index 00000000000..627becdbfb5 --- /dev/null +++ b/mysql-test/t/rpl_ndb_innodb_trans-slave.opt @@ -0,0 +1 @@ +--innodb diff --git a/mysql-test/t/rpl_ndb_innodb_trans.test b/mysql-test/t/rpl_ndb_innodb_trans.test new file mode 100644 index 00000000000..127c2464570 --- /dev/null +++ b/mysql-test/t/rpl_ndb_innodb_trans.test @@ -0,0 +1,66 @@ +# Test of a transaction mixing the two engines + +-- source include/have_ndb.inc +-- source include/have_innodb.inc +-- source include/master-slave.inc + +create table t1 (a int, unique(a)) engine=ndbcluster; +create table t2 (a int, unique(a)) engine=innodb; + + +begin; +insert into t1 values(1); +insert into t2 values(1); +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +delete from t1; +delete from t2; +begin; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +delete from t1; +delete from t2; +begin; +insert into t2 values(3),(4); +insert into t1 values(3),(4); +load data infile '../std_data_ln/rpl_loaddata.dat' into table t2; +load data infile '../std_data_ln/rpl_loaddata.dat' into table t1; +rollback; + +select count(*) from t1; +select count(*) from t2; +sync_slave_with_master; +select count(*) from t1; +select count(*) from t2; +connection master; + +drop table t1,t2; +sync_slave_with_master; diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index 8be17be3822..7479794eded 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -435,6 +435,86 @@ connection master; DROP PROCEDURE p1; + +# +# BUG#20438: CREATE statements for views, stored routines and triggers can be +# not replicable. +# + +--echo +--echo ---> Test for BUG#20438 + +# Prepare environment. + +--echo +--echo ---> Preparing environment... +--echo ---> connection: master +--connection master + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo +--echo ---> connection: master +--connection master + +# Test. + +--echo +--echo ---> Creating procedure... + +/*!50003 CREATE PROCEDURE p1() SET @a = 1 */; + +/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */; + +--echo +--echo ---> Checking on master... + +SHOW CREATE PROCEDURE p1; +SHOW CREATE FUNCTION f1; + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo ---> connection: master + +--echo +--echo ---> Checking on slave... + +SHOW CREATE PROCEDURE p1; +SHOW CREATE FUNCTION f1; + +# Cleanup. + +--echo +--echo ---> connection: master +--connection master + +--echo +--echo ---> Cleaning up... + +DROP PROCEDURE p1; +DROP FUNCTION f1; + +--save_master_pos +--connection slave +--sync_with_master +--connection master + + # cleanup connection master; drop table t1; diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test index 35f0a0b0a4b..3c8cbb97b31 100644 --- a/mysql-test/t/rpl_trigger.test +++ b/mysql-test/t/rpl_trigger.test @@ -331,6 +331,98 @@ SHOW TRIGGERS; RESET MASTER; +# Restart slave. + +connection slave; +START SLAVE; + + +# +# BUG#20438: CREATE statements for views, stored routines and triggers can be +# not replicable. +# + +--echo +--echo ---> Test for BUG#20438 + +# Prepare environment. + +--echo +--echo ---> Preparing environment... +--echo ---> connection: master +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo +--echo ---> connection: master +--connection master + +# Test. + +--echo +--echo ---> Creating objects... + +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); + +/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 + FOR EACH ROW + INSERT INTO t2 VALUES(NEW.c * 10) */; + +--echo +--echo ---> Inserting value... + +INSERT INTO t1 VALUES(1); + +--echo +--echo ---> Checking on master... + +SELECT * FROM t1; +SELECT * FROM t2; + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo ---> connection: master + +--echo +--echo ---> Checking on slave... + +SELECT * FROM t1; +SELECT * FROM t2; + +# Cleanup. + +--echo +--echo ---> connection: master +--connection master + +--echo +--echo ---> Cleaning up... + +DROP TABLE t1; +DROP TABLE t2; + +--save_master_pos +--connection slave +--sync_with_master +--connection master + # # End of tests diff --git a/mysql-test/t/rpl_view.test b/mysql-test/t/rpl_view.test index 0a0c6a6dddb..d0990b4fbee 100644 --- a/mysql-test/t/rpl_view.test +++ b/mysql-test/t/rpl_view.test @@ -45,3 +45,87 @@ drop table t1; sync_slave_with_master; --replace_column 2 # 5 # show binlog events limit 1,100; + + + +# +# BUG#20438: CREATE statements for views, stored routines and triggers can be +# not replicable. +# + +--echo +--echo ---> Test for BUG#20438 + +# Prepare environment. + +--echo +--echo ---> Preparing environment... +--echo ---> connection: master +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +--enable_warnings + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo +--echo ---> connection: master +--connection master + +# Test. + +--echo +--echo ---> Creating objects... + +CREATE TABLE t1(c INT); + +/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */; + +--echo +--echo ---> Inserting value... + +INSERT INTO t1 VALUES(1); + +--echo +--echo ---> Checking on master... + +SELECT * FROM t1; + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo ---> connection: master + +--echo +--echo ---> Checking on slave... + +SELECT * FROM t1; + +# Cleanup. + +--echo +--echo ---> connection: master +--connection master + +--echo +--echo ---> Cleaning up... + +DROP VIEW v1; +DROP TABLE t1; + +--save_master_pos +--connection slave +--sync_with_master +--connection master + diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 592e366f835..36b3749b4d7 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -2304,6 +2304,51 @@ INSERT INTO t1 VALUES (10); SELECT i='1e+01',i=1e+01, i in (1e+01,1e+01), i in ('1e+01','1e+01') FROM t1; DROP TABLE t1; +# +# Bug #21019: First result of SELECT COUNT(*) different than consecutive runs +# +CREATE TABLE t1 (a int, b int); +INSERT INTO t1 VALUES (1,1), (2,1), (4,10); + +CREATE TABLE t2 (a int PRIMARY KEY, b int, KEY b (b)); +INSERT INTO t2 VALUES (1,NULL), (2,10); +ALTER TABLE t1 ENABLE KEYS; + +EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +EXPLAIN SELECT STRAIGHT_JOIN SQL_NO_CACHE COUNT(*) FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +SELECT STRAIGHT_JOIN SQL_NO_CACHE * FROM t2, t1 WHERE t1.b = t2.b OR t2.b IS NULL; +DROP TABLE IF EXISTS t1,t2; +# +# Bug #20954 "avg(keyval) retuns 0.38 but max(keyval) returns an empty set" +# +--disable_ps_protocol +CREATE TABLE t1 (key1 float default NULL, UNIQUE KEY key1 (key1)); +CREATE TABLE t2 (key2 float default NULL, UNIQUE KEY key2 (key2)); +INSERT INTO t1 VALUES (0.3762),(0.3845),(0.6158),(0.7941); +INSERT INTO t2 VALUES (1.3762),(1.3845),(1.6158),(1.7941); + +explain select max(key1) from t1 where key1 <= 0.6158; +explain select max(key2) from t2 where key2 <= 1.6158; +explain select min(key1) from t1 where key1 >= 0.3762; +explain select min(key2) from t2 where key2 >= 1.3762; +explain select max(key1), min(key2) from t1, t2 +where key1 <= 0.6158 and key2 >= 1.3762; +explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; +explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; + +select max(key1) from t1 where key1 <= 0.6158; +select max(key2) from t2 where key2 <= 1.6158; +select min(key1) from t1 where key1 >= 0.3762; +select min(key2) from t2 where key2 >= 1.3762; +select max(key1), min(key2) from t1, t2 +where key1 <= 0.6158 and key2 >= 1.3762; +select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; +select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; + +DROP TABLE t1,t2; +--enable_ps_protocol + # End of 4.1 tests # @@ -2912,3 +2957,44 @@ SELECT 0.9888889889 * 1.011111411911; # prepare stmt from 'select 1 as " a "'; execute stmt; + +# +# Bug #21390: wrong estimate of rows after elimination of const tables +# + +CREATE TABLE t1 (a int NOT NULL PRIMARY KEY, b int NOT NULL); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4); + +CREATE TABLE t2 (c int NOT NULL, INDEX idx(c)); +INSERT INTO t2 VALUES + (1), (1), (1), (1), (1), (1), (1), (1), + (2), (2), (2), (2), + (3), (3), + (4); + +EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=1; +EXPLAIN SELECT b FROM t1, t2 WHERE b=c AND a=4; + +DROP TABLE t1, t2; + +# +# No matches for a join after substitution of a const table +# + +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, a int); +INSERT INTO t1 VALUES (1,2), (2,NULL), (3,2); + +CREATE TABLE t2 (b int, c INT, INDEX idx1(b)); +INSERT INTO t2 VALUES (2,1), (3,2); + +CREATE TABLE t3 (d int, e int, INDEX idx1(d)); +INSERT INTO t3 VALUES (2,10), (2,20), (1,30), (2,40), (2,50); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id + WHERE t1.id=2; +SELECT * FROM t1 LEFT JOIN t2 ON t2.b=t1.a INNER JOIN t3 ON t3.d=t1.id + WHERE t1.id=2; + + +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 6937cbe949d..65a81545c87 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -495,4 +495,15 @@ SHOW CREATE VIEW v1; DROP PROCEDURE p1; DROP VIEW v1; + +# +# Check that SHOW TABLES and SHOW COLUMNS give a error if there is no +# referenced database and table respectively. +# +--error ER_BAD_DB_ERROR +SHOW TABLES FROM no_such_database; +--error ER_NO_SUCH_TABLE +SHOW COLUMNS FROM no_such_table; + + # End of 5.0 tests. diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test index 0a26ea644f6..72efa831059 100644 --- a/mysql-test/t/sp-code.test +++ b/mysql-test/t/sp-code.test @@ -190,3 +190,25 @@ delimiter ;// show procedure code sudoku_solve; drop procedure sudoku_solve; + + +# +# Bug#19207: Final parenthesis omitted for CREATE INDEX in Stored +# Procedure +# +# Wrong criteria was used to distinguish the case when there was no +# lookahead performed in the parser. Bug affected only statements +# ending in one-character token without any optional tail, like CREATE +# INDEX and CALL. +# +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +--enable_warnings + +CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1); +SHOW PROCEDURE CODE p1; + +DROP PROCEDURE p1; + + +--echo End of 5.0 tests. diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index a4ab5d98922..abb36f040d2 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -899,6 +899,45 @@ begin flush tables; return 5; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin reset query cache; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin reset master; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin reset slave; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush hosts; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush privileges; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush tables with read lock; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush tables; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush logs; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush status; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush slave; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush master; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush des_key_file; +return 1; end| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create function bug8409() returns int begin flush user_resources; +return 1; end| # @@ -1707,6 +1746,28 @@ create aggregate function bug16896() returns int return 1; # +# BUG#14702: misleading error message when syntax error in CREATE +# PROCEDURE +# +# Misleading error message was given when IF NOT EXISTS was used in +# CREATE PROCEDURE. +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug14702; +--enable_warnings + +--error ER_PARSE_ERROR +CREATE IF NOT EXISTS PROCEDURE bug14702() +BEGIN +END; + +--error ER_PARSE_ERROR +CREATE PROCEDURE IF NOT EXISTS bug14702() +BEGIN +END; + + +# # BUG#NNNN: New bug synopsis # #--disable_warnings diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index d323b180216..a5d509f29b7 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -790,4 +790,80 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857'; DROP USER user19857@localhost; -# End of 5.0 bugs. +--disconnect con1root +--connection default + + +# +# BUG#18630: Arguments of suid routine calculated in wrong security +# context +# +# Arguments of suid routines were calculated in definer's security +# context instead of caller's context thus creating security hole. +# +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f_suid; +DROP PROCEDURE IF EXISTS p_suid; +DROP FUNCTION IF EXISTS f_evil; +--enable_warnings +DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%'; +FLUSH PRIVILEGES; + +CREATE TABLE t1 (i INT); +CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0; +CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0; + +CREATE USER mysqltest_u1@localhost; +# Thanks to this grant statement privileges of anonymous users on +# 'test' database are not applicable for mysqltest_u1@localhost. +GRANT EXECUTE ON test.* TO mysqltest_u1@localhost; + +delimiter |; +CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT + SQL SECURITY INVOKER +BEGIN + SET @a:= CURRENT_USER(); + SET @b:= (SELECT COUNT(*) FROM t1); + RETURN @b; +END| +delimiter ;| + +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil(); + +connect (conn1, localhost, mysqltest_u1,,); + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT COUNT(*) FROM t1; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT f_evil(); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT f_suid(f_evil()); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +CALL p_suid(f_evil()); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT * FROM v1; +SELECT @a, @b; + +disconnect conn1; +connection default; + +DROP VIEW v1; +DROP FUNCTION f_evil; +DROP USER mysqltest_u1@localhost; +DROP PROCEDURE p_suid; +DROP FUNCTION f_suid; +DROP TABLE t1; + +--echo End of 5.0 tests. diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 9a0003bab9c..4b0f463a9e3 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -5962,7 +5962,306 @@ call bug15217()| drop table t3| drop procedure bug15217| + +# +# BUG#21013: Performance Degrades when importing data that uses +# Trigger and Stored Procedure +# +# This is a performance and memory leak test. Run with large number +# passed to bug21013() procedure. +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug21013 | +--enable_warnings + +CREATE PROCEDURE bug21013(IN lim INT) +BEGIN + DECLARE i INT DEFAULT 0; + WHILE (i < lim) DO + SET @b = LOCATE(_latin1'b', @a, 1); + SET i = i + 1; + END WHILE; +END | + +SET @a = _latin2"aaaaaaaaaa" | +CALL bug21013(10) | + +DROP PROCEDURE bug21013 | + + +# +# BUG#16211: Stored function return type for strings is ignored +# + +# Prepare: create database with fixed, pre-defined character set. + +--disable_warnings +DROP DATABASE IF EXISTS mysqltest1| +DROP DATABASE IF EXISTS mysqltest2| +--enable_warnings + +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| +CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8| + +# Test case: + +use mysqltest1| + +# - Create two stored functions -- with and without explicit CHARSET-clause +# for return value; + +CREATE FUNCTION bug16211_f1() RETURNS CHAR(10) + RETURN ""| + +CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r + RETURN ""| + +CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10) + RETURN ""| + +CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r + RETURN ""| + +# - Check that CHARSET-clause is specified for the second function; + +SHOW CREATE FUNCTION bug16211_f1| +SHOW CREATE FUNCTION bug16211_f2| + +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| + +SELECT CHARSET(bug16211_f1())| +SELECT CHARSET(bug16211_f2())| + +SELECT CHARSET(mysqltest2.bug16211_f3())| +SELECT CHARSET(mysqltest2.bug16211_f4())| + +# - Alter database character set. + +ALTER DATABASE mysqltest1 CHARACTER SET cp1251| +ALTER DATABASE mysqltest2 CHARACTER SET cp1251| + +# - Check that CHARSET-clause has not changed. + +SHOW CREATE FUNCTION bug16211_f1| +SHOW CREATE FUNCTION bug16211_f2| + +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| + +SELECT CHARSET(bug16211_f1())| +SELECT CHARSET(bug16211_f2())| + +SELECT CHARSET(mysqltest2.bug16211_f3())| +SELECT CHARSET(mysqltest2.bug16211_f4())| + +# Cleanup. + +use test| + +DROP DATABASE mysqltest1| +DROP DATABASE mysqltest2| + + +# +# BUG#16676: Database CHARSET not used for stored procedures +# + +# Prepare: create database with fixed, pre-defined character set. + +--disable_warnings +DROP DATABASE IF EXISTS mysqltest1| +--enable_warnings + +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| + +# Test case: + +use mysqltest1| + +# - Create two stored procedures -- with and without explicit CHARSET-clause; + +CREATE PROCEDURE bug16676_p1( + IN p1 CHAR(10), + INOUT p2 CHAR(10), + OUT p3 CHAR(10)) +BEGIN + SELECT CHARSET(p1), COLLATION(p1); + SELECT CHARSET(p2), COLLATION(p2); + SELECT CHARSET(p3), COLLATION(p3); +END| + +CREATE PROCEDURE bug16676_p2( + IN p1 CHAR(10) CHARSET koi8r, + INOUT p2 CHAR(10) CHARSET cp1251, + OUT p3 CHAR(10) CHARSET greek) +BEGIN + SELECT CHARSET(p1), COLLATION(p1); + SELECT CHARSET(p2), COLLATION(p2); + SELECT CHARSET(p3), COLLATION(p3); +END| + +# - Call procedures. + +SET @v2 = 'b'| +SET @v3 = 'c'| + +CALL bug16676_p1('a', @v2, @v3)| +CALL bug16676_p2('a', @v2, @v3)| + +# Cleanup. + +use test| + +DROP DATABASE mysqltest1| # +# BUG#8153: Stored procedure with subquery and continue handler, wrong result +# + +--disable_warnings +drop table if exists t3| +drop table if exists t4| +drop procedure if exists bug8153_subselect| +drop procedure if exists bug8153_subselect_a| +drop procedure if exists bug8153_subselect_b| +drop procedure if exists bug8153_proc_a| +drop procedure if exists bug8153_proc_b| +--enable_warnings + +create table t3 (a int)| +create table t4 (a int)| +insert into t3 values (1), (1), (2), (3)| +insert into t4 values (1), (1)| + +## Testing the use case reported in Bug#8153 + +create procedure bug8153_subselect() +begin + declare continue handler for sqlexception + begin + select 'statement failed'; + end; + update t3 set a=a+1 where (select a from t4 where a=1) is null; + select 'statement after update'; +end| + +call bug8153_subselect()| +select * from t3| + +call bug8153_subselect()| +select * from t3| + +drop procedure bug8153_subselect| + +## Testing a subselect with a non local handler + +create procedure bug8153_subselect_a() +begin + declare continue handler for sqlexception + begin + select 'in continue handler'; + end; + + select 'reachable code a1'; + call bug8153_subselect_b(); + select 'reachable code a2'; +end| + +create procedure bug8153_subselect_b() +begin + select 'reachable code b1'; + update t3 set a=a+1 where (select a from t4 where a=1) is null; + select 'unreachable code b2'; +end| + +call bug8153_subselect_a()| +select * from t3| + +call bug8153_subselect_a()| +select * from t3| + +drop procedure bug8153_subselect_a| +drop procedure bug8153_subselect_b| + +## Testing extra use cases, found while investigating +## This is related to BUG#18787, with a non local handler + +create procedure bug8153_proc_a() +begin + declare continue handler for sqlexception + begin + select 'in continue handler'; + end; + + select 'reachable code a1'; + call bug8153_proc_b(); + select 'reachable code a2'; +end| + +create procedure bug8153_proc_b() +begin + select 'reachable code b1'; + select no_such_function(); + select 'unreachable code b2'; +end| + +call bug8153_proc_a()| + +drop procedure bug8153_proc_a| +drop procedure bug8153_proc_b| +drop table t3| +drop table t4| + +# +# BUG#19862: Sort with filesort by function evaluates function twice +# +--disable_warnings +drop procedure if exists bug19862| +--enable_warnings +CREATE TABLE t11 (a INT)| +CREATE TABLE t12 (a INT)| +CREATE FUNCTION bug19862(x INT) RETURNS INT + BEGIN + INSERT INTO t11 VALUES (x); + RETURN x+1; + END| +INSERT INTO t12 VALUES (1), (2)| +SELECT bug19862(a) FROM t12 ORDER BY 1| +SELECT * FROM t11| +DROP TABLE t11, t12| +DROP FUNCTION bug19862| # Bug#21002 "Derived table not selecting from a "real" table fails in JOINs" # # A regression caused by the fix for Bug#18444: for derived tables we should @@ -5987,6 +6286,42 @@ select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2| use test| drop table t3| + +# +# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause. +# + +# Prepare. + +--disable_warnings +DROP PROCEDURE IF EXISTS bug16899_p1| +DROP FUNCTION IF EXISTS bug16899_f1| +--enable_warnings + +--error ER_WRONG_STRING_LENGTH +CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1() +BEGIN + SET @a = 1; +END| + +--error ER_WRONG_STRING_LENGTH +CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY + FUNCTION bug16899_f1() RETURNS INT +BEGIN + RETURN 1; +END| + + +# +# BUG#21416: SP: Recursion level higher than zero needed for non-recursive call +# +--disable_warnings +drop procedure if exists bug21416| +--enable_warnings +create procedure bug21416() show create procedure bug21416| +call bug21416()| +drop procedure bug21416| + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/sp.test.orig b/mysql-test/t/sp.test.orig deleted file mode 100644 index a4b99620344..00000000000 --- a/mysql-test/t/sp.test.orig +++ /dev/null @@ -1,5716 +0,0 @@ -# -# Basic stored PROCEDURE tests -# -# Please keep this file free of --error cases and other -# things that will not run in a single debugged mysqld -# process (e.g. master-slave things). -# -# Test cases for bugs are added at the end. See template there. -# -# Tests that require --error go into sp-error.test -# Tests that require inndb go into sp_trans.test -# Tests that check privilege and security issues go to sp-security.test. -# Tests that require multiple connections, except security/privilege tests, -# go to sp-thread. -# Tests that uses 'goto' to into sp-goto.test (currently disabled) -# Tests that destroys system tables (e.g. mysql.proc) for error testing -# go to sp-destruct. - -use test; - -# Test tables -# -# t1 and t2 are reused throughout the file, and dropped at the end. -# t3 and up are created and dropped when needed. -# ---disable_warnings -drop table if exists t1,t2,t3,t4; ---enable_warnings -create table t1 ( - id char(16) not null default '', - data int not null -); -create table t2 ( - s char(16), - i int, - d double -); - - -# Single statement, no params. ---disable_warnings -drop procedure if exists foo42; ---enable_warnings -create procedure foo42() - insert into test.t1 values ("foo", 42); - -call foo42(); -select * from t1; -delete from t1; -drop procedure foo42; - - -# Single statement, two IN params. ---disable_warnings -drop procedure if exists bar; ---enable_warnings -create procedure bar(x char(16), y int) - insert into test.t1 values (x, y); - -call bar("bar", 666); -select * from t1; -delete from t1; -# Don't drop procedure yet... - - -# Now for multiple statements... -delimiter |; - -# Empty statement ---disable_warnings -drop procedure if exists empty| ---enable_warnings -create procedure empty() -begin -end| - -call empty()| -drop procedure empty| - -# Scope test. This is legal (warnings might be possible in the future, -# but for the time being, we just accept it). ---disable_warnings -drop procedure if exists scope| ---enable_warnings -create procedure scope(a int, b float) -begin - declare b int; - declare c float; - - begin - declare c int; - end; -end| - -drop procedure scope| - -# Two statements. ---disable_warnings -drop procedure if exists two| ---enable_warnings -create procedure two(x1 char(16), x2 char(16), y int) -begin - insert into test.t1 values (x1, y); - insert into test.t1 values (x2, y); -end| - -call two("one", "two", 3)| -select * from t1| -delete from t1| -drop procedure two| - - -# Simple test of local variables and SET. ---disable_warnings -drop procedure if exists locset| ---enable_warnings -create procedure locset(x char(16), y int) -begin - declare z1, z2 int; - set z1 = y; - set z2 = z1+2; - insert into test.t1 values (x, z2); -end| - -call locset("locset", 19)| -select * from t1| -delete from t1| -drop procedure locset| - - -# In some contexts local variables are not recognized -# (and in some, you have to qualify the identifier). ---disable_warnings -drop procedure if exists setcontext| ---enable_warnings -create procedure setcontext() -begin - declare data int default 2; - - insert into t1 (id, data) values ("foo", 1); - replace t1 set data = data, id = "bar"; - update t1 set id = "kaka", data = 3 where t1.data = data; -end| - -call setcontext()| -select * from t1| -delete from t1| -drop procedure setcontext| - - -# Set things to null -create table t3 ( d date, i int, f double, s varchar(32) )| - ---disable_warnings -drop procedure if exists nullset| ---enable_warnings -create procedure nullset() -begin - declare ld date; - declare li int; - declare lf double; - declare ls varchar(32); - - set ld = null, li = null, lf = null, ls = null; - insert into t3 values (ld, li, lf, ls); - - insert into t3 (i, f, s) values ((ld is null), 1, "ld is null"), - ((li is null), 1, "li is null"), - ((li = 0), null, "li = 0"), - ((lf is null), 1, "lf is null"), - ((lf = 0), null, "lf = 0"), - ((ls is null), 1, "ls is null"); -end| - -call nullset()| -select * from t3| -drop table t3| -drop procedure nullset| - - -# The peculiar (non-standard) mixture of variables types in SET. ---disable_warnings -drop procedure if exists mixset| ---enable_warnings -create procedure mixset(x char(16), y int) -begin - declare z int; - - set @z = y, z = 666, max_join_size = 100; - insert into test.t1 values (x, z); -end| - -call mixset("mixset", 19)| -show variables like 'max_join_size'| -select id,data,@z from t1| -delete from t1| -drop procedure mixset| - - -# Multiple CALL statements, one with OUT parameter. ---disable_warnings -drop procedure if exists zip| ---enable_warnings -create procedure zip(x char(16), y int) -begin - declare z int; - call zap(y, z); - call bar(x, z); -end| - -# SET local variables and OUT parameter. ---disable_warnings -drop procedure if exists zap| ---enable_warnings -create procedure zap(x int, out y int) -begin - declare z int; - set z = x+1, y = z; -end| - -call zip("zip", 99)| -select * from t1| -delete from t1| -drop procedure zip| -drop procedure bar| - -# Top-level OUT parameter -call zap(7, @zap)| -select @zap| - -drop procedure zap| - - -# "Deep" calls... ---disable_warnings -drop procedure if exists c1| ---enable_warnings -create procedure c1(x int) - call c2("c", x)| ---disable_warnings -drop procedure if exists c2| ---enable_warnings -create procedure c2(s char(16), x int) - call c3(x, s)| ---disable_warnings -drop procedure if exists c3| ---enable_warnings -create procedure c3(x int, s char(16)) - call c4("level", x, s)| ---disable_warnings -drop procedure if exists c4| ---enable_warnings -create procedure c4(l char(8), x int, s char(16)) - insert into t1 values (concat(l,s), x)| - -call c1(42)| -select * from t1| -delete from t1| -drop procedure c1| -drop procedure c2| -drop procedure c3| -drop procedure c4| - -# INOUT test ---disable_warnings -drop procedure if exists iotest| ---enable_warnings -create procedure iotest(x1 char(16), x2 char(16), y int) -begin - call inc2(x2, y); - insert into test.t1 values (x1, y); -end| - ---disable_warnings -drop procedure if exists inc2| ---enable_warnings -create procedure inc2(x char(16), y int) -begin - call inc(y); - insert into test.t1 values (x, y); -end| - ---disable_warnings -drop procedure if exists inc| ---enable_warnings -create procedure inc(inout io int) - set io = io + 1| - -call iotest("io1", "io2", 1)| -select * from t1| -delete from t1| -drop procedure iotest| -drop procedure inc2| - -# Propagating top-level @-vars ---disable_warnings -drop procedure if exists incr| ---enable_warnings -create procedure incr(inout x int) - call inc(x)| - -# Before -select @zap| -call incr(@zap)| -# After -select @zap| - -drop procedure inc| -drop procedure incr| - -# Call-by-value test -# The expected result is: -# ("cbv2", 4) -# ("cbv1", 4711) ---disable_warnings -drop procedure if exists cbv1| ---enable_warnings -create procedure cbv1() -begin - declare y int default 3; - - call cbv2(y+1, y); - insert into test.t1 values ("cbv1", y); -end| - ---disable_warnings -drop procedure if exists cbv2| ---enable_warnings -create procedure cbv2(y1 int, inout y2 int) -begin - set y2 = 4711; - insert into test.t1 values ("cbv2", y1); -end| - -call cbv1()| -select * from t1| -delete from t1| -drop procedure cbv1| -drop procedure cbv2| - - -# Subselect arguments - -insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)| - ---disable_warnings -drop procedure if exists sub1| ---enable_warnings -create procedure sub1(id char(16), x int) - insert into test.t1 values (id, x)| - ---disable_warnings -drop procedure if exists sub2| ---enable_warnings -create procedure sub2(id char(16)) -begin - declare x int; - set x = (select sum(t.i) from test.t2 t); - insert into test.t1 values (id, x); -end| - ---disable_warnings -drop procedure if exists sub3| ---enable_warnings -create function sub3(i int) returns int - return i+1| - -call sub1("sub1a", (select 7))| -call sub1("sub1b", (select max(i) from t2))| ---error ER_OPERAND_COLUMNS -call sub1("sub1c", (select i,d from t2 limit 1))| -call sub1("sub1d", (select 1 from (select 1) a))| -call sub2("sub2")| -select * from t1| -select sub3((select max(i) from t2))| -drop procedure sub1| -drop procedure sub2| -drop function sub3| -delete from t1| -delete from t2| - -# Basic tests of the flow control constructs - -# Just test on 'x'... ---disable_warnings -drop procedure if exists a0| ---enable_warnings -create procedure a0(x int) -while x do - set x = x-1; - insert into test.t1 values ("a0", x); -end while| - -call a0(3)| -select * from t1| -delete from t1| -drop procedure a0| - - -# The same, but with a more traditional test. ---disable_warnings -drop procedure if exists a| ---enable_warnings -create procedure a(x int) -while x > 0 do - set x = x-1; - insert into test.t1 values ("a", x); -end while| - -call a(3)| -select * from t1| -delete from t1| -drop procedure a| - - -# REPEAT ---disable_warnings -drop procedure if exists b| ---enable_warnings -create procedure b(x int) -repeat - insert into test.t1 values (repeat("b",3), x); - set x = x-1; -until x = 0 end repeat| - -call b(3)| -select * from t1| -delete from t1| -drop procedure b| - - -# Check that repeat isn't parsed the wrong way ---disable_warnings -drop procedure if exists b2| ---enable_warnings -create procedure b2(x int) -repeat(select 1 into outfile 'b2'); - insert into test.t1 values (repeat("b2",3), x); - set x = x-1; -until x = 0 end repeat| - -# We don't actually want to call it. -drop procedure b2| - - -# Labelled WHILE with ITERATE (pointless really) ---disable_warnings -drop procedure if exists c| ---enable_warnings -create procedure c(x int) -hmm: while x > 0 do - insert into test.t1 values ("c", x); - set x = x-1; - iterate hmm; - insert into test.t1 values ("x", x); -end while hmm| - -call c(3)| -select * from t1| -delete from t1| -drop procedure c| - - -# Labelled WHILE with LEAVE ---disable_warnings -drop procedure if exists d| ---enable_warnings -create procedure d(x int) -hmm: while x > 0 do - insert into test.t1 values ("d", x); - set x = x-1; - leave hmm; - insert into test.t1 values ("x", x); -end while| - -call d(3)| -select * from t1| -delete from t1| -drop procedure d| - - -# LOOP, with simple IF statement ---disable_warnings -drop procedure if exists e| ---enable_warnings -create procedure e(x int) -foo: loop - if x = 0 then - leave foo; - end if; - insert into test.t1 values ("e", x); - set x = x-1; -end loop foo| - -call e(3)| -select * from t1| -delete from t1| -drop procedure e| - - -# A full IF statement ---disable_warnings -drop procedure if exists f| ---enable_warnings -create procedure f(x int) -if x < 0 then - insert into test.t1 values ("f", 0); -elseif x = 0 then - insert into test.t1 values ("f", 1); -else - insert into test.t1 values ("f", 2); -end if| - -call f(-2)| -call f(0)| -call f(4)| -select * from t1| -delete from t1| -drop procedure f| - - -# This form of CASE is really just syntactic sugar for IF-ELSEIF-... ---disable_warnings -drop procedure if exists g| ---enable_warnings -create procedure g(x int) -case -when x < 0 then - insert into test.t1 values ("g", 0); -when x = 0 then - insert into test.t1 values ("g", 1); -else - insert into test.t1 values ("g", 2); -end case| - -call g(-42)| -call g(0)| -call g(1)| -select * from t1| -delete from t1| -drop procedure g| - - -# The "simple CASE" ---disable_warnings -drop procedure if exists h| ---enable_warnings -create procedure h(x int) -case x -when 0 then - insert into test.t1 values ("h0", x); -when 1 then - insert into test.t1 values ("h1", x); -else - insert into test.t1 values ("h?", x); -end case| - -call h(0)| -call h(1)| -call h(17)| -select * from t1| -delete from t1| -drop procedure h| - - -# It's actually possible to LEAVE a BEGIN-END block ---disable_warnings -drop procedure if exists i| ---enable_warnings -create procedure i(x int) -foo: -begin - if x = 0 then - leave foo; - end if; - insert into test.t1 values ("i", x); -end foo| - -call i(0)| -call i(3)| -select * from t1| -delete from t1| -drop procedure i| - - -# SELECT with one of more result set sent back to the clinet -insert into t1 values ("foo", 3), ("bar", 19)| -insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)| - ---disable_warnings -drop procedure if exists sel1| ---enable_warnings -create procedure sel1() -begin - select * from t1; -end| - -call sel1()| -drop procedure sel1| - ---disable_warnings -drop procedure if exists sel2| ---enable_warnings -create procedure sel2() -begin - select * from t1; - select * from t2; -end| - -call sel2()| -drop procedure sel2| -delete from t1| -delete from t2| - -# SELECT INTO local variables ---disable_warnings -drop procedure if exists into_test| ---enable_warnings -create procedure into_test(x char(16), y int) -begin - insert into test.t1 values (x, y); - select id,data into x,y from test.t1 limit 1; - insert into test.t1 values (concat(x, "2"), y+2); -end| - -call into_test("into", 100)| -select * from t1| -delete from t1| -drop procedure into_test| - - -# SELECT INTO with a mix of local and global variables ---disable_warnings -drop procedure if exists into_tes2| ---enable_warnings -create procedure into_test2(x char(16), y int) -begin - insert into test.t1 values (x, y); - select id,data into x,@z from test.t1 limit 1; - insert into test.t1 values (concat(x, "2"), y+2); -end| - -call into_test2("into", 100)| -select id,data,@z from t1| -delete from t1| -drop procedure into_test2| - - -# SELECT * INTO ... (bug test) ---disable_warnings -drop procedure if exists into_test3| ---enable_warnings -create procedure into_test3() -begin - declare x char(16); - declare y int; - - select * into x,y from test.t1 limit 1; - insert into test.t2 values (x, y, 0.0); -end| - -insert into t1 values ("into3", 19)| -# Two call needed for bug test -call into_test3()| -call into_test3()| -select * from t2| -delete from t1| -delete from t2| -drop procedure into_test3| - - -# SELECT INTO with no data is a warning ("no data", which we will -# not see normally). When not caught, execution proceeds. ---disable_warnings -drop procedure if exists into_test4| ---enable_warnings -create procedure into_test4() -begin - declare x int; - - select data into x from test.t1 limit 1; - insert into test.t3 values ("into4", x); -end| - -delete from t1| -create table t3 ( s char(16), d int)| -call into_test4()| -select * from t3| -insert into t1 values ("i4", 77)| -call into_test4()| -select * from t3| -delete from t1| -drop table t3| -drop procedure into_test4| - - -# These two (and the two procedures above) caused an assert() to fail in -# sql_base.cc:lock_tables() at some point. ---disable_warnings -drop procedure if exists into_outfile| ---enable_warnings -create procedure into_outfile(x char(16), y int) -begin - insert into test.t1 values (x, y); - select * into outfile "../tmp/spout" from test.t1; - insert into test.t1 values (concat(x, "2"), y+2); -end| - ---system rm -f $MYSQLTEST_VARDIR/tmp/spout -call into_outfile("ofile", 1)| ---system rm -f $MYSQLTEST_VARDIR/tmp/spout -delete from t1| -drop procedure into_outfile| - ---disable_warnings -drop procedure if exists into_dumpfile| ---enable_warnings -create procedure into_dumpfile(x char(16), y int) -begin - insert into test.t1 values (x, y); - select * into dumpfile "../tmp/spdump" from test.t1 limit 1; - insert into test.t1 values (concat(x, "2"), y+2); -end| - ---system rm -f $MYSQLTEST_VARDIR/tmp/spdump -call into_dumpfile("dfile", 1)| ---system rm -f $MYSQLTEST_VARDIR/tmp/spdump -delete from t1| -drop procedure into_dumpfile| - ---disable_warnings -drop procedure if exists create_select| ---enable_warnings -create procedure create_select(x char(16), y int) -begin - insert into test.t1 values (x, y); - create temporary table test.t3 select * from test.t1; - insert into test.t3 values (concat(x, "2"), y+2); -end| - -call create_select("cs", 90)| -select * from t1, t3| -drop table t3| -delete from t1| -drop procedure create_select| - - -# A minimal, constant FUNCTION. ---disable_warnings -drop function if exists e| ---enable_warnings -create function e() returns double - return 2.7182818284590452354| - -set @e = e()| -select e(), @e| - -# A minimal function with one argument ---disable_warnings -drop function if exists inc| ---enable_warnings -create function inc(i int) returns int - return i+1| - -select inc(1), inc(99), inc(-71)| - -# A minimal function with two arguments ---disable_warnings -drop function if exists mul| ---enable_warnings -create function mul(x int, y int) returns int - return x*y| - -select mul(1,1), mul(3,5), mul(4711, 666)| - -# A minimal string function ---disable_warnings -drop function if exists append| ---enable_warnings -create function append(s1 char(8), s2 char(8)) returns char(16) - return concat(s1, s2)| - -select append("foo", "bar")| - -# A function with flow control ---disable_warnings -drop function if exists fac| ---enable_warnings -create function fac(n int unsigned) returns bigint unsigned -begin - declare f bigint unsigned default 1; - - while n > 1 do - set f = f * n; - set n = n - 1; - end while; - return f; -end| - -select fac(1), fac(2), fac(5), fac(10)| - -# Nested calls ---disable_warnings -drop function if exists fun| ---enable_warnings -create function fun(d double, i int, u int unsigned) returns double - return mul(inc(i), fac(u)) / e()| - -select fun(2.3, 3, 5)| - - -# Various function calls in differen statements - -insert into t2 values (append("xxx", "yyy"), mul(4,3), e())| -insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))| - -# Disable PS because double's give a bit different values ---disable_ps_protocol -select * from t2 where s = append("a", "b")| -select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2)| -select * from t2 where d = e()| -select * from t2| ---enable_ps_protocol -delete from t2| - -drop function e| -drop function inc| -drop function mul| -drop function append| -drop function fun| - - -# -# CONDITIONs and HANDLERs -# - ---disable_warnings -drop procedure if exists hndlr1| ---enable_warnings -create procedure hndlr1(val int) -begin - declare x int default 0; - declare foo condition for 1136; - declare bar condition for sqlstate '42S98'; # Just for testing syntax - declare zip condition for sqlstate value '42S99'; # Just for testing syntax - declare continue handler for foo set x = 1; - - insert into test.t1 values ("hndlr1", val, 2); # Too many values - if (x) then - insert into test.t1 values ("hndlr1", val); # This instead then - end if; -end| - -call hndlr1(42)| -select * from t1| -delete from t1| -drop procedure hndlr1| - ---disable_warnings -drop procedure if exists hndlr2| ---enable_warnings -create procedure hndlr2(val int) -begin - declare x int default 0; - - begin - declare exit handler for sqlstate '21S01' set x = 1; - - insert into test.t1 values ("hndlr2", val, 2); # Too many values - end; - - insert into test.t1 values ("hndlr2", x); -end| - -call hndlr2(42)| -select * from t1| -delete from t1| -drop procedure hndlr2| - - ---disable_warnings -drop procedure if exists hndlr3| ---enable_warnings -create procedure hndlr3(val int) -begin - declare x int default 0; - declare continue handler for sqlexception # Any error - begin - declare z int; - - set z = 2 * val; - set x = 1; - end; - - if val < 10 then - begin - declare y int; - - set y = val + 10; - insert into test.t1 values ("hndlr3", y, 2); # Too many values - if x then - insert into test.t1 values ("hndlr3", y); - end if; - end; - end if; -end| - -call hndlr3(3)| -select * from t1| -delete from t1| -drop procedure hndlr3| - - -# Variables might be uninitialized when using handlers -# (Otherwise the compiler can detect if a variable is not set, but -# not in this case.) -create table t3 ( id char(16), data int )| - ---disable_warnings -drop procedure if exists hndlr4| ---enable_warnings -create procedure hndlr4() -begin - declare x int default 0; - declare val int; # No default - declare continue handler for sqlstate '02000' set x=1; - - select data into val from test.t3 where id='z' limit 1; # No hits - - insert into test.t3 values ('z', val); -end| - -call hndlr4()| -select * from t3| -drop table t3| -drop procedure hndlr4| - - -# -# Cursors -# ---disable_warnings -drop procedure if exists cur1| ---enable_warnings -create procedure cur1() -begin - declare a char(16); - declare b int; - declare c double; - declare done int default 0; - declare c cursor for select * from test.t2; - declare continue handler for sqlstate '02000' set done = 1; - - open c; - repeat - fetch c into a, b, c; - if not done then - insert into test.t1 values (a, b+c); - end if; - until done end repeat; - close c; -end| - -insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)| -call cur1()| -select * from t1| -drop procedure cur1| - -create table t3 ( s char(16), i int )| - ---disable_warnings -drop procedure if exists cur2| ---enable_warnings -create procedure cur2() -begin - declare done int default 0; - declare c1 cursor for select id,data from test.t1; - declare c2 cursor for select i from test.t2; - declare continue handler for sqlstate '02000' set done = 1; - - open c1; - open c2; - repeat - begin - declare a char(16); - declare b,c int; - - fetch from c1 into a, b; - fetch next from c2 into c; - if not done then - if b < c then - insert into test.t3 values (a, b); - else - insert into test.t3 values (a, c); - end if; - end if; - end; - until done end repeat; - close c1; - close c2; -end| - -call cur2()| -select * from t3| -delete from t1| -delete from t2| -drop table t3| -drop procedure cur2| - - -# The few characteristics we parse ---disable_warnings -drop procedure if exists chistics| ---enable_warnings -create procedure chistics() - language sql - modifies sql data - not deterministic - sql security definer - comment 'Characteristics procedure test' - insert into t1 values ("chistics", 1)| - -show create procedure chistics| -# Call it, just to make sure. -call chistics()| -select * from t1| -delete from t1| -alter procedure chistics sql security invoker| -show create procedure chistics| -drop procedure chistics| - ---disable_warnings -drop function if exists chistics| ---enable_warnings -create function chistics() returns int - language sql - deterministic - sql security invoker - comment 'Characteristics procedure test' - return 42| - -show create function chistics| -# Call it, just to make sure. -select chistics()| -alter function chistics - no sql - comment 'Characteristics function test'| -show create function chistics| -drop function chistics| - - -# Check mode settings -insert into t1 values ("foo", 1), ("bar", 2), ("zip", 3)| - -set @@sql_mode = 'ANSI'| -delimiter $| ---disable_warnings -drop procedure if exists modes$ ---enable_warnings -create procedure modes(out c1 int, out c2 int) -begin - declare done int default 0; - declare x int; - declare c cursor for select data from t1; - declare continue handler for sqlstate '02000' set done = 1; - - select 1 || 2 into c1; - set c2 = 0; - open c; - repeat - fetch c into x; - if not done then - set c2 = c2 + 1; - end if; - until done end repeat; - close c; -end$ -delimiter |$ -set @@sql_mode = ''| - -set sql_select_limit = 1| -call modes(@c1, @c2)| -set sql_select_limit = default| - -select @c1, @c2| -delete from t1| -drop procedure modes| - - -# Check that dropping a database without routines works. -# (Dropping with routines is tested in sp-security.test) -# First an empty db. -create database sp_db1| -drop database sp_db1| - -# Again, with a table. -create database sp_db2| -use sp_db2| -# Just put something in here... -create table t3 ( s char(4), t int )| -insert into t3 values ("abcd", 42), ("dcba", 666)| -use test| -drop database sp_db2| - -# And yet again, with just a procedure. -create database sp_db3| -use sp_db3| ---disable_warnings -drop procedure if exists dummy| ---enable_warnings -create procedure dummy(out x int) - set x = 42| -use test| -drop database sp_db3| -# Check that it's gone -select type,db,name from mysql.proc where db = 'sp_db3'| - - -# ROW_COUNT() function after a CALL -# We test the other cases here too, although it's not strictly SP specific ---disable_warnings -drop procedure if exists rc| ---enable_warnings -create procedure rc() -begin - delete from t1; - insert into t1 values ("a", 1), ("b", 2), ("c", 3); -end| - -call rc()| -select row_count()| ---disable_ps_protocol -update t1 set data=42 where id = "b"; -select row_count()| ---enable_ps_protocol -delete from t1| -select row_count()| -delete from t1| -select row_count()| -select * from t1| -select row_count()| -drop procedure rc| - - -# -# Let us test how well new locking scheme works. -# - -# Let us prepare playground ---disable_warnings -drop function if exists f0| -drop function if exists f1| -drop function if exists f2| -drop function if exists f3| -drop function if exists f4| -drop function if exists f5| -drop function if exists f6| -drop function if exists f7| -drop function if exists f8| -drop function if exists f9| -drop function if exists f10| -drop function if exists f11| -drop function if exists f12_1| -drop function if exists f12_2| -drop view if exists v0| -drop view if exists v1| -drop view if exists v2| ---enable_warnings -delete from t1| -delete from t2| -insert into t1 values ("a", 1), ("b", 2) | -insert into t2 values ("a", 1, 1.0), ("b", 2, 2.0), ("c", 3, 3.0) | - -# Test the simplest function using tables -create function f1() returns int - return (select sum(data) from t1)| -select f1()| -# This should work too (and give 2 rows as result) -select id, f1() from t1| - -# Function which uses two instances of table simultaneously -create function f2() returns int - return (select data from t1 where data <= (select sum(data) from t1) limit 1)| -select f2()| -select id, f2() from t1| - -# Function which uses the same table twice in different queries -create function f3() returns int -begin - declare n int; - declare m int; - set n:= (select min(data) from t1); - set m:= (select max(data) from t1); - return n < m; -end| -select f3()| -select id, f3() from t1| - -# Calling two functions using same table -select f1(), f3()| -select id, f1(), f3() from t1| - -# Function which uses two different tables -create function f4() returns double - return (select d from t1, t2 where t1.data = t2.i and t1.id= "b")| -select f4()| -select s, f4() from t2| - -# Recursive functions which due to this recursion require simultaneous -# access to several instance of the same table won't work -create function f5(i int) returns int -begin - if i <= 0 then - return 0; - elseif i = 1 then - return (select count(*) from t1 where data = i); - else - return (select count(*) + f5( i - 1) from t1 where data = i); - end if; -end| -select f5(1)| -# Since currently recursive functions are disallowed ER_SP_NO_RECURSION -# error will be returned, once we will allow them error about -# insufficient number of locked tables will be returned instead. ---error ER_SP_NO_RECURSION -select f5(2)| ---error ER_SP_NO_RECURSION -select f5(3)| - -# OTOH this should work -create function f6() returns int -begin - declare n int; - set n:= f1(); - return (select count(*) from t1 where data <= f7() and data <= n); -end| -create function f7() returns int - return (select sum(data) from t1 where data <= f1())| -select f6()| -select id, f6() from t1| - -# -# Let us test how new locking work with views -# -# The most trivial view -create view v1 (a) as select f1()| -select * from v1| -select id, a from t1, v1| -select * from v1, v1 as v| -# A bit more complex construction -create view v2 (a) as select a*10 from v1| -select * from v2| -select id, a from t1, v2| -select * from v1, v2| - -# Nice example where the same view is used on -# on different expression levels -create function f8 () returns int - return (select count(*) from v2)| - -select *, f8() from v1| - -# Let us test what will happen if function is missing -drop function f1| ---error 1356 -select * from v1| - -# And what will happen if we have recursion which involves -# views and functions ? -create function f1() returns int - return (select sum(data) from t1) + (select sum(data) from v1)| ---error ER_SP_NO_RECURSION -select f1()| ---error ER_SP_NO_RECURSION -select * from v1| ---error ER_SP_NO_RECURSION -select * from v2| -# Back to the normal cases -drop function f1| -create function f1() returns int - return (select sum(data) from t1)| - -# Let us also test some weird cases where no real tables is used -create function f0() returns int - return (select * from (select 100) as r)| -select f0()| -select *, f0() from (select 1) as t| -create view v0 as select f0()| -select * from v0| -select *, f0() from v0| - -# -# Let us test how well prelocking works with explicit LOCK TABLES. -# -lock tables t1 read, t1 as t11 read| -# These should work well -select f3()| -select id, f3() from t1 as t11| -# Degenerate cases work too :) -select f0()| -select * from v0| -select *, f0() from v0, (select 123) as d1| -# But these should not ! ---error 1100 -select id, f3() from t1| ---error 1100 -select f4()| -unlock tables| - -# Let us test how LOCK TABLES which implicitly depends on functions -# works -lock tables v2 read, mysql.proc read| -select * from v2| -select * from v1| -# These should not work as we have too little instances of tables locked ---error 1100 -select * from v1, t1| ---error 1100 -select f4()| -unlock tables| - -# Tests for handling of temporary tables in functions. -# -# Unlike for permanent tables we should be able to create, use -# and drop such tables in functions. -# -# Simplest function using temporary table. It is also test case for bug -# #12198 "Temporary table aliasing does not work inside stored functions" -create function f9() returns int -begin - declare a, b int; - drop temporary table if exists t3; - create temporary table t3 (id int); - insert into t3 values (1), (2), (3); - set a:= (select count(*) from t3); - set b:= (select count(*) from t3 t3_alias); - return a + b; -end| -# This will emit warning as t3 was not existing before. -select f9()| -select f9() from t1 limit 1| - -# Function which uses both temporary and permanent tables. -create function f10() returns int -begin - drop temporary table if exists t3; - create temporary table t3 (id int); - insert into t3 select id from t4; - return (select count(*) from t3); -end| -# Check that we don't ignore completely tables used in function ---error ER_NO_SUCH_TABLE -select f10()| -create table t4 as select 1 as id| -select f10()| - -# Practical cases which we don't handle well (yet) -# -# Function which does not work because of well-known and documented -# limitation of MySQL. We can't use the several instances of the -# same temporary table in statement. -create function f11() returns int -begin - drop temporary table if exists t3; - create temporary table t3 (id int); - insert into t3 values (1), (2), (3); - return (select count(*) from t3 as a, t3 as b); -end| ---error ER_CANT_REOPEN_TABLE -select f11()| ---error ER_CANT_REOPEN_TABLE -select f11() from t1| -# We don't handle temporary tables used by nested functions well -create function f12_1() returns int -begin - drop temporary table if exists t3; - create temporary table t3 (id int); - insert into t3 values (1), (2), (3); - return f12_2(); -end| -create function f12_2() returns int - return (select count(*) from t3)| -# We need clean start to get error -drop temporary table t3| ---error ER_NO_SUCH_TABLE -select f12_1()| ---error ER_NO_SUCH_TABLE -select f12_1() from t1 limit 1| - -# Cleanup -drop function f0| -drop function f1| -drop function f2| -drop function f3| -drop function f4| -drop function f5| -drop function f6| -drop function f7| -drop function f8| -drop function f9| -drop function f10| -drop function f11| -drop function f12_1| -drop function f12_2| -drop view v0| -drop view v1| -drop view v2| -delete from t1 | -delete from t2 | -drop table t4| - -# End of non-bug tests - - -# -# Some "real" examples -# - -# fac - ---disable_warnings -drop table if exists t3| ---enable_warnings -create table t3 (n int unsigned not null primary key, f bigint unsigned)| - ---disable_warnings -drop procedure if exists ifac| ---enable_warnings -create procedure ifac(n int unsigned) -begin - declare i int unsigned default 1; - - if n > 20 then - set n = 20; # bigint overflow otherwise - end if; - while i <= n do - begin - insert into test.t3 values (i, fac(i)); - set i = i + 1; - end; - end while; -end| - -call ifac(20)| -select * from t3| -drop table t3| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -show function status like '%f%'| -drop procedure ifac| -drop function fac| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -show function status like '%f%'| - - -# primes - ---disable_warnings -drop table if exists t3| ---enable_warnings - -create table t3 ( - i int unsigned not null primary key, - p bigint unsigned not null -)| - -insert into t3 values - ( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13), - ( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31), - (10, 37), (11, 41), (12, 43), (13, 47), (14, 53), - (15, 59), (16, 61), (17, 67), (18, 71), (19, 73), - (20, 79), (21, 83), (22, 89), (23, 97), (24, 101), - (25, 103), (26, 107), (27, 109), (28, 113), (29, 127), - (30, 131), (31, 137), (32, 139), (33, 149), (34, 151), - (35, 157), (36, 163), (37, 167), (38, 173), (39, 179), - (40, 181), (41, 191), (42, 193), (43, 197), (44, 199)| - ---disable_warnings -drop procedure if exists opp| ---enable_warnings -create procedure opp(n bigint unsigned, out pp bool) -begin - declare r double; - declare b, s bigint unsigned default 0; - - set r = sqrt(n); - - again: - loop - if s = 45 then - set b = b+200, s = 0; - else - begin - declare p bigint unsigned; - - select t.p into p from test.t3 t where t.i = s; - if b+p > r then - set pp = 1; - leave again; - end if; - if mod(n, b+p) = 0 then - set pp = 0; - leave again; - end if; - set s = s+1; - end; - end if; - end loop; -end| - ---disable_warnings -drop procedure if exists ip| ---enable_warnings -create procedure ip(m int unsigned) -begin - declare p bigint unsigned; - declare i int unsigned; - - set i=45, p=201; - - while i < m do - begin - declare pp bool default 0; - - call opp(p, pp); - if pp then - insert into test.t3 values (i, p); - set i = i+1; - end if; - set p = p+2; - end; - end while; -end| -show create procedure opp| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -show procedure status like '%p%'| - -# This isn't the fastest way in the world to compute prime numbers, so -# don't be too ambitious. ;-) -call ip(200)| -# We don't want to select the entire table here, just pick a few -# examples. -# The expected result is: -# i p -# --- ---- -# 45 211 -# 100 557 -# 199 1229 -select * from t3 where i=45 or i=100 or i=199| -drop table t3| -drop procedure opp| -drop procedure ip| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -show procedure status like '%p%'| - - -# Fibonacci, for recursion test. (Yet Another Numerical series :) -# ---disable_warnings -drop table if exists t3| ---enable_warnings -create table t3 ( f bigint unsigned not null )| - -# We deliberately do it the awkward way, fetching the last two -# values from the table, in order to exercise various statements -# and table accesses at each turn. ---disable_warnings -drop procedure if exists fib| ---enable_warnings -create procedure fib(n int unsigned) -begin - if n > 1 then - begin - declare x, y bigint unsigned; - declare c cursor for select f from t3 order by f desc limit 2; - - open c; - fetch c into y; - fetch c into x; - close c; - insert into t3 values (x+y); - call fib(n-1); - end; - end if; -end| - -# Enable recursion -set @@max_sp_recursion_depth= 20| - -# Minimum test: recursion of 3 levels - -insert into t3 values (0), (1)| - -call fib(3)| - -select * from t3 order by f asc| - -delete from t3| - -# The original test, 20 levels, ran into memory limits on some machines -# and builds. Try 10 instead... - -insert into t3 values (0), (1)| - -call fib(10)| - -select * from t3 order by f asc| -drop table t3| -drop procedure fib| -set @@max_sp_recursion_depth= 0| - -# -# Comment & suid -# - ---disable_warnings -drop procedure if exists bar| ---enable_warnings -create procedure bar(x char(16), y int) - comment "111111111111" sql security invoker - insert into test.t1 values (x, y)| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -show procedure status like 'bar'| -alter procedure bar comment "2222222222" sql security definer| -alter procedure bar comment "3333333333"| -alter procedure bar| -show create procedure bar| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -show procedure status like 'bar'| -drop procedure bar| - -# -# rexecution -# ---disable_warnings -drop procedure if exists p1| ---enable_warnings -create procedure p1 () - select (select s1 from t3) from t3| - -create table t3 (s1 int)| - -call p1()| -insert into t3 values (1)| -call p1()| -drop procedure p1| -drop table t3| - -# -# backticks -# ---disable_warnings -drop function if exists foo| ---enable_warnings -create function `foo` () returns int - return 5| -select `foo` ()| -drop function `foo`| - -# -# Implicit LOCK/UNLOCK TABLES for table access in functions -# - ---disable_warnings -drop function if exists t1max| ---enable_warnings -create function t1max() returns int -begin - declare x int; - select max(data) into x from t1; - return x; -end| - -insert into t1 values ("foo", 3), ("bar", 2), ("zip", 5), ("zap", 1)| -select t1max()| -drop function t1max| - -create table t3 ( - v char(16) not null primary key, - c int unsigned not null -)| - -create function getcount(s char(16)) returns int -begin - declare x int; - - select count(*) into x from t3 where v = s; - if x = 0 then - insert into t3 values (s, 1); - else - update t3 set c = c+1 where v = s; - end if; - return x; -end| - -select * from t1 where data = getcount("bar")| -select * from t3| -select getcount("zip")| -select getcount("zip")| -select * from t3| -select getcount(id) from t1 where data = 3| -select getcount(id) from t1 where data = 5| -select * from t3| -drop table t3| -drop function getcount| - - -# Test cases for different combinations of condition handlers in nested -# begin-end blocks in stored procedures. -# -# Note that the standard specifies that the most specific handler should -# be triggered even if it's an outer handler masked by a less specific -# handler in an inner block. -# Note also that '02000' is more specific than NOT FOUND; there might be -# other '02xxx' states, even if we currently do not issue them in any -# situation (e.g. '02001'). -# -# The combinations we test are these: -# -# Inner -# errcode sqlstate not found sqlwarning sqlexception -# Outer +------------+------------+------------+------------+------------+ -#errcode | h_ee (i) | h_es (o) | h_en (o) | h_ew (o) | h_ex (o) | -#sqlstate | h_se (i) | h_ss (i) | h_sn (o) | h_sw (o) | h_sx (o) | -#not found | h_ne (i) | h_ns (i) | h_nn (i) | | | -#sqlwarning | h_we (i) | h_ws (i) | | h_ww (i) | | -#sqlexception | h_xe (i) | h_xs (i) | | | h_xx (i) | -# +------------+---------------------------------------------------+ -# -# (i) means that the inner handler is the one that should be invoked, -# (o) means that the outer handler should be invoked. -# -# ('not found', 'sqlwarning' and 'sqlexception' are mutually exclusive, hence -# no tests for those combinations.) -# - ---disable_warnings -drop table if exists t3| -drop procedure if exists h_ee| -drop procedure if exists h_es| -drop procedure if exists h_en| -drop procedure if exists h_ew| -drop procedure if exists h_ex| -drop procedure if exists h_se| -drop procedure if exists h_ss| -drop procedure if exists h_sn| -drop procedure if exists h_sw| -drop procedure if exists h_sx| -drop procedure if exists h_ne| -drop procedure if exists h_ns| -drop procedure if exists h_nn| -drop procedure if exists h_we| -drop procedure if exists h_ws| -drop procedure if exists h_ww| -drop procedure if exists h_xe| -drop procedure if exists h_xs| -drop procedure if exists h_xx| ---enable_warnings - -# smallint - to get out of range warnings -# primary key - to get constraint errors -create table t3 (a smallint primary key)| - -insert into t3 (a) values (1)| - -create procedure h_ee() - deterministic -begin - declare continue handler for 1062 -- ER_DUP_ENTRY - select 'Outer (bad)' as 'h_ee'; - - begin - declare continue handler for 1062 -- ER_DUP_ENTRY - select 'Inner (good)' as 'h_ee'; - - insert into t3 values (1); - end; -end| - -create procedure h_es() - deterministic -begin - declare continue handler for 1062 -- ER_DUP_ENTRY - select 'Outer (good)' as 'h_es'; - - begin - -- integrity constraint violation - declare continue handler for sqlstate '23000' - select 'Inner (bad)' as 'h_es'; - - insert into t3 values (1); - end; -end| - -create procedure h_en() - deterministic -begin - declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA - select 'Outer (good)' as 'h_en'; - - begin - declare x int; - declare continue handler for sqlstate '02000' -- no data - select 'Inner (bad)' as 'h_en'; - - select a into x from t3 where a = 42; - end; -end| - -create procedure h_ew() - deterministic -begin - declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE - select 'Outer (good)' as 'h_ew'; - - begin - declare continue handler for sqlwarning - select 'Inner (bad)' as 'h_ew'; - - insert into t3 values (123456789012); - end; - delete from t3; - insert into t3 values (1); -end| - -create procedure h_ex() - deterministic -begin - declare continue handler for 1062 -- ER_DUP_ENTRY - select 'Outer (good)' as 'h_ex'; - - begin - declare continue handler for sqlexception - select 'Inner (bad)' as 'h_ex'; - - insert into t3 values (1); - end; -end| - -create procedure h_se() - deterministic -begin - -- integrity constraint violation - declare continue handler for sqlstate '23000' - select 'Outer (bad)' as 'h_se'; - - begin - declare continue handler for 1062 -- ER_DUP_ENTRY - select 'Inner (good)' as 'h_se'; - - insert into t3 values (1); - end; -end| - -create procedure h_ss() - deterministic -begin - -- integrity constraint violation - declare continue handler for sqlstate '23000' - select 'Outer (bad)' as 'h_ss'; - - begin - -- integrity constraint violation - declare continue handler for sqlstate '23000' - select 'Inner (good)' as 'h_ss'; - - insert into t3 values (1); - end; -end| - -create procedure h_sn() - deterministic -begin - -- Note: '02000' is more specific than NOT FOUND ; - -- there might be other not found states - declare continue handler for sqlstate '02000' -- no data - select 'Outer (good)' as 'h_sn'; - - begin - declare x int; - declare continue handler for not found - select 'Inner (bad)' as 'h_sn'; - - select a into x from t3 where a = 42; - end; -end| - -create procedure h_sw() - deterministic -begin - -- data exception - numeric value out of range - declare continue handler for sqlstate '22003' - select 'Outer (good)' as 'h_sw'; - - begin - declare continue handler for sqlwarning - select 'Inner (bad)' as 'h_sw'; - - insert into t3 values (123456789012); - end; - delete from t3; - insert into t3 values (1); -end| - -create procedure h_sx() - deterministic -begin - -- integrity constraint violation - declare continue handler for sqlstate '23000' - select 'Outer (good)' as 'h_sx'; - - begin - declare continue handler for sqlexception - select 'Inner (bad)' as 'h_sx'; - - insert into t3 values (1); - end; -end| - -create procedure h_ne() - deterministic -begin - declare continue handler for not found - select 'Outer (bad)' as 'h_ne'; - - begin - declare x int; - declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA - select 'Inner (good)' as 'h_ne'; - - select a into x from t3 where a = 42; - end; -end| - -create procedure h_ns() - deterministic -begin - declare continue handler for not found - select 'Outer (bad)' as 'h_ns'; - - begin - declare x int; - declare continue handler for sqlstate '02000' -- no data - select 'Inner (good)' as 'h_ns'; - - select a into x from t3 where a = 42; - end; -end| - -create procedure h_nn() - deterministic -begin - declare continue handler for not found - select 'Outer (bad)' as 'h_nn'; - - begin - declare x int; - declare continue handler for not found - select 'Inner (good)' as 'h_nn'; - - select a into x from t3 where a = 42; - end; -end| - -create procedure h_we() - deterministic -begin - declare continue handler for sqlwarning - select 'Outer (bad)' as 'h_we'; - - begin - declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE - select 'Inner (good)' as 'h_we'; - - insert into t3 values (123456789012); - end; - delete from t3; - insert into t3 values (1); -end| - -create procedure h_ws() - deterministic -begin - declare continue handler for sqlwarning - select 'Outer (bad)' as 'h_ws'; - - begin - -- data exception - numeric value out of range - declare continue handler for sqlstate '22003' - select 'Inner (good)' as 'h_ws'; - - insert into t3 values (123456789012); - end; - delete from t3; - insert into t3 values (1); -end| - -create procedure h_ww() - deterministic -begin - declare continue handler for sqlwarning - select 'Outer (bad)' as 'h_ww'; - - begin - declare continue handler for sqlwarning - select 'Inner (good)' as 'h_ww'; - - insert into t3 values (123456789012); - end; - delete from t3; - insert into t3 values (1); -end| - -create procedure h_xe() - deterministic -begin - declare continue handler for sqlexception - select 'Outer (bad)' as 'h_xe'; - - begin - declare continue handler for 1062 -- ER_DUP_ENTRY - select 'Inner (good)' as 'h_xe'; - - insert into t3 values (1); - end; -end| - -create procedure h_xs() - deterministic -begin - declare continue handler for sqlexception - select 'Outer (bad)' as 'h_xs'; - - begin - -- integrity constraint violation - declare continue handler for sqlstate '23000' - select 'Inner (good)' as 'h_xs'; - - insert into t3 values (1); - end; -end| - -create procedure h_xx() - deterministic -begin - declare continue handler for sqlexception - select 'Outer (bad)' as 'h_xx'; - - begin - declare continue handler for sqlexception - select 'Inner (good)' as 'h_xx'; - - insert into t3 values (1); - end; -end| - -call h_ee()| -call h_es()| -call h_en()| -call h_ew()| -call h_ex()| -call h_se()| -call h_ss()| -call h_sn()| -call h_sw()| -call h_sx()| -call h_ne()| -call h_ns()| -call h_nn()| -call h_we()| -call h_ws()| -call h_ww()| -call h_xe()| -call h_xs()| -call h_xx()| - -drop table t3| -drop procedure h_ee| -drop procedure h_es| -drop procedure h_en| -drop procedure h_ew| -drop procedure h_ex| -drop procedure h_se| -drop procedure h_ss| -drop procedure h_sn| -drop procedure h_sw| -drop procedure h_sx| -drop procedure h_ne| -drop procedure h_ns| -drop procedure h_nn| -drop procedure h_we| -drop procedure h_ws| -drop procedure h_ww| -drop procedure h_xe| -drop procedure h_xs| -drop procedure h_xx| - - -# -# Test cases for old bugs -# - -# -# BUG#822 -# ---disable_warnings -drop procedure if exists bug822| ---enable_warnings -create procedure bug822(a_id char(16), a_data int) -begin - declare n int; - select count(*) into n from t1 where id = a_id and data = a_data; - if n = 0 then - insert into t1 (id, data) values (a_id, a_data); - end if; -end| - -delete from t1| -call bug822('foo', 42)| -call bug822('foo', 42)| -call bug822('bar', 666)| -select * from t1| -delete from t1| -drop procedure bug822| - -# -# BUG#1495 -# ---disable_warnings -drop procedure if exists bug1495| ---enable_warnings -create procedure bug1495() -begin - declare x int; - - select data into x from t1 order by id limit 1; - if x > 10 then - insert into t1 values ("less", x-10); - else - insert into t1 values ("more", x+10); - end if; -end| - -insert into t1 values ('foo', 12)| -call bug1495()| -delete from t1 where id='foo'| -insert into t1 values ('bar', 7)| -call bug1495()| -delete from t1 where id='bar'| -select * from t1| -delete from t1| -drop procedure bug1495| - -# -# BUG#1547 -# ---disable_warnings -drop procedure if exists bug1547| ---enable_warnings -create procedure bug1547(s char(16)) -begin - declare x int; - - select data into x from t1 where s = id limit 1; - if x > 10 then - insert into t1 values ("less", x-10); - else - insert into t1 values ("more", x+10); - end if; -end| - -insert into t1 values ("foo", 12), ("bar", 7)| -call bug1547("foo")| -call bug1547("bar")| -select * from t1| -delete from t1| -drop procedure bug1547| - -# -# BUG#1656 -# ---disable_warnings -drop table if exists t70| ---enable_warnings -create table t70 (s1 int,s2 int)| -insert into t70 values (1,2)| - ---disable_warnings -drop procedure if exists bug1656| ---enable_warnings -create procedure bug1656(out p1 int, out p2 int) - select * into p1, p1 from t70| - -call bug1656(@1, @2)| -select @1, @2| -drop table t70| -drop procedure bug1656| - -# -# BUG#1862 -# -create table t3(a int)| - ---disable_warnings -drop procedure if exists bug1862| ---enable_warnings -create procedure bug1862() -begin - insert into t3 values(2); - flush tables; -end| - -call bug1862()| -# the second call caused a segmentation -call bug1862()| -select * from t3| -drop table t3| -drop procedure bug1862| - -# -# BUG#1874 -# ---disable_warnings -drop procedure if exists bug1874| ---enable_warnings -create procedure bug1874() -begin - declare x int; - declare y double; - select max(data) into x from t1; - insert into t2 values ("max", x, 0); - select min(data) into x from t1; - insert into t2 values ("min", x, 0); - select sum(data) into x from t1; - insert into t2 values ("sum", x, 0); - select avg(data) into y from t1; - insert into t2 values ("avg", 0, y); -end| - -insert into t1 (data) values (3), (1), (5), (9), (4)| -call bug1874()| -select * from t2| -delete from t1| -delete from t2| -drop procedure bug1874| - -# -# BUG#2260 -# ---disable_warnings -drop procedure if exists bug2260| ---enable_warnings -create procedure bug2260() -begin - declare v1 int; - declare c1 cursor for select data from t1; - declare continue handler for not found set @x2 = 1; - - open c1; - fetch c1 into v1; - set @x2 = 2; - close c1; -end| - -call bug2260()| -select @x2| -drop procedure bug2260| - -# -# BUG#2267 "Lost connect if stored procedure has SHOW FUNCTION STATUS" -# ---disable_warnings -drop procedure if exists bug2267_1| ---enable_warnings -create procedure bug2267_1() -begin - show procedure status; -end| - ---disable_warnings -drop procedure if exists bug2267_2| ---enable_warnings -create procedure bug2267_2() -begin - show function status; -end| - ---disable_warnings -drop procedure if exists bug2267_3| ---enable_warnings -create procedure bug2267_3() -begin - show create procedure bug2267_1; -end| - ---disable_warnings -drop procedure if exists bug2267_4| -drop function if exists bug2267_4| ---enable_warnings -create procedure bug2267_4() -begin - show create function bug2267_4; -end| -create function bug2267_4() returns int return 100| - ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -call bug2267_1()| ---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00' -call bug2267_2()| -call bug2267_3()| -call bug2267_4()| - -drop procedure bug2267_1| -drop procedure bug2267_2| -drop procedure bug2267_3| -drop procedure bug2267_4| -drop function bug2267_4| - -# -# BUG#2227 -# ---disable_warnings -drop procedure if exists bug2227| ---enable_warnings -create procedure bug2227(x int) -begin - declare y float default 2.6; - declare z char(16) default "zzz"; - - select 1.3, x, y, 42, z; -end| - -call bug2227(9)| -drop procedure bug2227| - -# -# BUG#2614 "Stored procedure with INSERT ... SELECT that does not -# contain any tables crashes server" -# ---disable_warnings -drop procedure if exists bug2614| ---enable_warnings -create procedure bug2614() -begin - drop table if exists t3; - create table t3 (id int default '0' not null); - insert into t3 select 12; - insert into t3 select * from t3; -end| - ---disable_warnings -call bug2614()| ---enable_warnings -call bug2614()| -drop table t3| -drop procedure bug2614| - -# -# BUG#2674 -# ---disable_warnings -drop function if exists bug2674| ---enable_warnings -create function bug2674() returns int - return @@sort_buffer_size| - -set @osbs = @@sort_buffer_size| -set @@sort_buffer_size = 262000| -select bug2674()| -drop function bug2674| -set @@sort_buffer_size = @osbs| - -# -# BUG#3259 -# ---disable_warnings -drop procedure if exists bug3259_1 | ---enable_warnings -create procedure bug3259_1 () begin end| ---disable_warnings -drop procedure if exists BUG3259_2 | ---enable_warnings -create procedure BUG3259_2 () begin end| ---disable_warnings -drop procedure if exists Bug3259_3 | ---enable_warnings -create procedure Bug3259_3 () begin end| - -call BUG3259_1()| -call BUG3259_1()| -call bug3259_2()| -call Bug3259_2()| -call bug3259_3()| -call bUG3259_3()| - -drop procedure bUg3259_1| -drop procedure BuG3259_2| -drop procedure BUG3259_3| - -# -# BUG#2772 -# ---disable_warnings -drop function if exists bug2772| ---enable_warnings -create function bug2772() returns char(10) character set latin2 - return 'a'| - -select bug2772()| -drop function bug2772| - -# -# BUG#2776 -# ---disable_warnings -drop procedure if exists bug2776_1| ---enable_warnings -create procedure bug2776_1(out x int) -begin - declare v int; - - set v = default; - set x = v; -end| - ---disable_warnings -drop procedure if exists bug2776_2| ---enable_warnings -create procedure bug2776_2(out x int) -begin - declare v int default 42; - - set v = default; - set x = v; -end| - -set @x = 1| -call bug2776_1(@x)| -select @x| -call bug2776_2(@x)| -select @x| -drop procedure bug2776_1| -drop procedure bug2776_2| - -# -# BUG#2780 -# -create table t3 (s1 smallint)| - -insert into t3 values (123456789012)| - ---disable_warnings -drop procedure if exists bug2780| ---enable_warnings -create procedure bug2780() -begin - declare exit handler for sqlwarning set @x = 1; - - set @x = 0; - insert into t3 values (123456789012); - insert into t3 values (0); -end| - -call bug2780()| -select @x| -select * from t3| - -drop procedure bug2780| -drop table t3| - -# -# BUG#1863 -# -create table t3 (content varchar(10) )| -insert into t3 values ("test1")| -insert into t3 values ("test2")| -create table t4 (f1 int, rc int, t3 int)| - ---disable_warnings -drop procedure if exists bug1863| ---enable_warnings -create procedure bug1863(in1 int) -begin - - declare ind int default 0; - declare t1 int; - declare t2 int; - declare t3 int; - - declare rc int default 0; - declare continue handler for 1065 set rc = 1; - - drop temporary table if exists temp_t1; - create temporary table temp_t1 ( - f1 int auto_increment, f2 varchar(20), primary key (f1) - ); - - insert into temp_t1 (f2) select content from t3; - - select f2 into t3 from temp_t1 where f1 = 10; - - if (rc) then - insert into t4 values (1, rc, t3); - end if; - - insert into t4 values (2, rc, t3); - -end| - -call bug1863(10)| -call bug1863(10)| -select * from t4| - -drop procedure bug1863| -drop temporary table temp_t1; -drop table t3, t4| - -# -# BUG#2656 -# - -create table t3 ( - OrderID int not null, - MarketID int, - primary key (OrderID) -)| - -create table t4 ( - MarketID int not null, - Market varchar(60), - Status char(1), - primary key (MarketID) -)| - -insert t3 (OrderID,MarketID) values (1,1)| -insert t3 (OrderID,MarketID) values (2,2)| -insert t4 (MarketID,Market,Status) values (1,"MarketID One","A")| -insert t4 (MarketID,Market,Status) values (2,"MarketID Two","A")| - ---disable_warnings -drop procedure if exists bug2656_1| ---enable_warnings -create procedure bug2656_1() -begin - select - m.Market - from t4 m JOIN t3 o - ON o.MarketID != 1 and o.MarketID = m.MarketID; -end | - ---disable_warnings -drop procedure if exists bug2656_2| ---enable_warnings -create procedure bug2656_2() -begin - select - m.Market - from - t4 m, t3 o - where - m.MarketID != 1 and m.MarketID = o.MarketID; - -end | - -call bug2656_1()| -call bug2656_1()| -call bug2656_2()| -call bug2656_2()| -drop procedure bug2656_1| -drop procedure bug2656_2| -drop table t3, t4| - - -# -# BUG#3426 -# ---disable_warnings -drop procedure if exists bug3426| ---enable_warnings -create procedure bug3426(in_time int unsigned, out x int) -begin - if in_time is null then - set @stamped_time=10; - set x=1; - else - set @stamped_time=in_time; - set x=2; - end if; -end| - -call bug3426(1000, @i)| -select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time| -call bug3426(NULL, @i)| -select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time| -# Clear SP cache -alter procedure bug3426 sql security invoker| -call bug3426(NULL, @i)| -select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time| -call bug3426(1000, @i)| -select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time| - -drop procedure bug3426| - -# -# BUG#3448 -# ---disable_warnings -create table t3 ( - a int primary key, - ach char(1) -) engine = innodb| - -create table t4 ( - b int primary key , - bch char(1) -) engine = innodb| ---enable_warnings - -insert into t3 values (1 , 'aCh1' ) , ('2' , 'aCh2')| -insert into t4 values (1 , 'bCh1' )| - ---disable_warnings -drop procedure if exists bug3448| ---enable_warnings -create procedure bug3448() - select * from t3 inner join t4 on t3.a = t4.b| - -select * from t3 inner join t4 on t3.a = t4.b| -call bug3448()| -call bug3448()| - -drop procedure bug3448| -drop table t3, t4| - - -# -# BUG#3734 -# -create table t3 ( - id int unsigned auto_increment not null primary key, - title VARCHAR(200), - body text, - fulltext (title,body) -)| - -insert into t3 (title,body) values - ('MySQL Tutorial','DBMS stands for DataBase ...'), - ('How To Use MySQL Well','After you went through a ...'), - ('Optimizing MySQL','In this tutorial we will show ...'), - ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), - ('MySQL vs. YourSQL','In the following database comparison ...'), - ('MySQL Security','When configured properly, MySQL ...')| - ---disable_warnings -drop procedure if exists bug3734 | ---enable_warnings -create procedure bug3734 (param1 varchar(100)) - select * from t3 where match (title,body) against (param1)| - -call bug3734('database')| -call bug3734('Security')| - -drop procedure bug3734| -drop table t3| - -# -# BUG#3863 -# ---disable_warnings -drop procedure if exists bug3863| ---enable_warnings -create procedure bug3863() -begin - set @a = 0; - while @a < 5 do - set @a = @a + 1; - end while; -end| - -call bug3863()| -select @a| -call bug3863()| -select @a| - -drop procedure bug3863| - -# -# BUG#2460 -# - -create table t3 ( - id int(10) unsigned not null default 0, - rid int(10) unsigned not null default 0, - msg text not null, - primary key (id), - unique key rid (rid, id) -)| - ---disable_warnings -drop procedure if exists bug2460_1| ---enable_warnings -create procedure bug2460_1(in v int) -begin - ( select n0.id from t3 as n0 where n0.id = v ) - union - ( select n0.id from t3 as n0, t3 as n1 - where n0.id = n1.rid and n1.id = v ) - union - ( select n0.id from t3 as n0, t3 as n1, t3 as n2 - where n0.id = n1.rid and n1.id = n2.rid and n2.id = v ); -end| - -call bug2460_1(2)| -call bug2460_1(2)| -insert into t3 values (1, 1, 'foo'), (2, 1, 'bar'), (3, 1, 'zip zap')| -call bug2460_1(2)| -call bug2460_1(2)| - ---disable_warnings -drop procedure if exists bug2460_2| ---enable_warnings -create procedure bug2460_2() -begin - drop table if exists t3; - create temporary table t3 (s1 int); - insert into t3 select 1 union select 1; -end| - -call bug2460_2()| -call bug2460_2()| -select * from t3| - -drop procedure bug2460_1| -drop procedure bug2460_2| -drop table t3| - - -# -# BUG#2564 -# -set @@sql_mode = ''| ---disable_warnings -drop procedure if exists bug2564_1| ---enable_warnings -create procedure bug2564_1() - comment 'Joe''s procedure' - insert into `t1` values ("foo", 1)| - -set @@sql_mode = 'ANSI_QUOTES'| ---disable_warnings -drop procedure if exists bug2564_2| ---enable_warnings -create procedure bug2564_2() - insert into "t1" values ('foo', 1)| - -delimiter $| -set @@sql_mode = ''$ ---disable_warnings -drop function if exists bug2564_3$ ---enable_warnings -create function bug2564_3(x int, y int) returns int - return x || y$ - -set @@sql_mode = 'ANSI'$ ---disable_warnings -drop function if exists bug2564_4$ ---enable_warnings -create function bug2564_4(x int, y int) returns int - return x || y$ -delimiter |$ - -set @@sql_mode = ''| -show create procedure bug2564_1| -show create procedure bug2564_2| -show create function bug2564_3| -show create function bug2564_4| - -drop procedure bug2564_1| -drop procedure bug2564_2| -drop function bug2564_3| -drop function bug2564_4| - -# -# BUG#3132 -# ---disable_warnings -drop function if exists bug3132| ---enable_warnings -create function bug3132(s char(20)) returns char(50) - return concat('Hello, ', s, '!')| - -select bug3132('Bob') union all select bug3132('Judy')| -drop function bug3132| - -# -# BUG#3843 -# ---disable_warnings -drop procedure if exists bug3843| ---enable_warnings -create procedure bug3843() - analyze table t1| - -# Testing for packets out of order -call bug3843()| -call bug3843()| -select 1+2| - -drop procedure bug3843| - -# -# BUG#3368 -# -create table t3 ( s1 char(10) )| -insert into t3 values ('a'), ('b')| - ---disable_warnings -drop procedure if exists bug3368| ---enable_warnings -create procedure bug3368(v char(10)) -begin - select group_concat(v) from t3; -end| - -call bug3368('x')| -call bug3368('yz')| -drop procedure bug3368| -drop table t3| - -# -# BUG#4579 -# -create table t3 (f1 int, f2 int)| -insert into t3 values (1,1)| - ---disable_warnings -drop procedure if exists bug4579_1| ---enable_warnings -create procedure bug4579_1 () -begin - declare sf1 int; - - select f1 into sf1 from t3 where f1=1 and f2=1; - update t3 set f2 = f2 + 1 where f1=1 and f2=1; - call bug4579_2(); -end| - ---disable_warnings -drop procedure if exists bug4579_2| ---enable_warnings -create procedure bug4579_2 () -begin -end| - -call bug4579_1()| -call bug4579_1()| -call bug4579_1()| - -drop procedure bug4579_1| -drop procedure bug4579_2| -drop table t3| - -# -# BUG#2773: Function's data type ignored in stored procedures -# ---disable_warnings -drop procedure if exists bug2773| ---enable_warnings - -create function bug2773() returns int return null| -create table t3 as select bug2773()| -show create table t3| -drop table t3| -drop function bug2773| - -# -# BUG#3788: Stored procedure packet error -# ---disable_warnings -drop procedure if exists bug3788| ---enable_warnings - -create function bug3788() returns date return cast("2005-03-04" as date)| -select bug3788()| -drop function bug3788| - -create function bug3788() returns binary(1) return 5| -select bug3788()| -drop function bug3788| - - -# -# BUG#4726 -# -create table t3 (f1 int, f2 int, f3 int)| -insert into t3 values (1,1,1)| - ---disable_warnings -drop procedure if exists bug4726| ---enable_warnings -create procedure bug4726() -begin - declare tmp_o_id INT; - declare tmp_d_id INT default 1; - - while tmp_d_id <= 2 do - begin - select f1 into tmp_o_id from t3 where f2=1 and f3=1; - set tmp_d_id = tmp_d_id + 1; - end; - end while; -end| - -call bug4726()| -call bug4726()| -call bug4726()| - -drop procedure bug4726| -drop table t3| - -# -# BUG#4318 -# - ---disable_parsing # Don't know if HANDLER commands can work with SPs, or at all.. -create table t3 (s1 int)| -insert into t3 values (3), (4)| - ---disable_warnings -drop procedure if exists bug4318| ---enable_warnings -create procedure bug4318() - handler t3 read next| - -handler t3 open| -# Expect no results, as tables are closed, but there shouldn't be any errors -call bug4318()| -call bug4318()| -handler t3 close| - -drop procedure bug4318| -drop table t3| ---enable_parsing - -# -# BUG#4902: Stored procedure with SHOW WARNINGS leads to packet error -# -# Added tests for most other show commands we could find too. -# (Skipping those already tested, and the ones depending on optional handlers.) -# -# Note: This will return a large number of results of different formats, -# which makes it impossible to filter with --replace_column. -# It's possible that some of these are not deterministic across -# platforms. If so, just remove the offending command. -# ---disable_warnings -drop procedure if exists bug4902| ---enable_warnings -create procedure bug4902() -begin - show charset like 'foo'; - show collation like 'foo'; - show column types; - show create table t1; - show create database test; - show databases like 'foo'; - show errors; - show columns from t1; - show grants for 'root'@'localhost'; - show keys from t1; - show open tables like 'foo'; - show privileges; - show status like 'foo'; - show tables like 'foo'; - show variables like 'foo'; - show warnings; -end| ---disable_parsing -show binlog events; -show storage engines; -show master status; -show slave hosts; -show slave status; ---enable_parsing - -call bug4902()| -call bug4902()| - -drop procedure bug4902| - -# We need separate SP for SHOW PROCESSLIST since we want use replace_column ---disable_warnings -drop procedure if exists bug4902_2| ---enable_warnings -create procedure bug4902_2() -begin - show processlist; -end| ---replace_column 1 # 6 # 3 localhost -call bug4902_2()| ---replace_column 1 # 6 # 3 localhost -call bug4902_2()| -drop procedure bug4902_2| - -# -# BUG#4904 -# ---disable_warnings -drop procedure if exists bug4904| ---enable_warnings -create procedure bug4904() -begin - declare continue handler for sqlstate 'HY000' begin end; - - create table t2 as select * from t3; -end| - --- error 1146 -call bug4904()| - -drop procedure bug4904| - -create table t3 (s1 char character set latin1, s2 char character set latin2)| - ---disable_warnings -drop procedure if exists bug4904| ---enable_warnings -create procedure bug4904 () -begin - declare continue handler for sqlstate 'HY000' begin end; - - select s1 from t3 union select s2 from t3; -end| - -call bug4904()| - -drop procedure bug4904| -drop table t3| - -# -# BUG#336 -# ---disable_warnings -drop procedure if exists bug336| ---enable_warnings -create procedure bug336(out y int) -begin - declare x int; - set x = (select sum(t.data) from test.t1 t); - set y = x; -end| - -insert into t1 values ("a", 2), ("b", 3)| -call bug336(@y)| -select @y| -delete from t1| -drop procedure bug336| - -# -# BUG#3157 -# ---disable_warnings -drop procedure if exists bug3157| ---enable_warnings -create procedure bug3157() -begin - if exists(select * from t1) then - set @n= @n + 1; - end if; - if (select count(*) from t1) then - set @n= @n + 1; - end if; -end| - -set @n = 0| -insert into t1 values ("a", 1)| -call bug3157()| -select @n| -delete from t1| -drop procedure bug3157| - -# -# BUG#5251: mysql changes creation time of a procedure/function when altering -# ---disable_warnings -drop procedure if exists bug5251| ---enable_warnings -create procedure bug5251() -begin -end| - -select created into @c1 from mysql.proc - where db='test' and name='bug5251'| ---sleep 2 -alter procedure bug5251 comment 'foobar'| -select count(*) from mysql.proc - where db='test' and name='bug5251' and created = @c1| - -drop procedure bug5251| - -# -# BUG#5279: Stored procedure packets out of order if CHECKSUM TABLE -# ---disable_warnings -drop procedure if exists bug5251| ---enable_warnings -create procedure bug5251() - checksum table t1| - -call bug5251()| -call bug5251()| -drop procedure bug5251| - -# -# BUG#5287: Stored procedure crash if leave outside loop -# ---disable_warnings -drop procedure if exists bug5287| ---enable_warnings -create procedure bug5287(param1 int) -label1: - begin - declare c cursor for select 5; - - loop - if param1 >= 0 then - leave label1; - end if; - end loop; -end| -call bug5287(1)| -drop procedure bug5287| - - -# -# BUG#5307: Stored procedure allows statement after BEGIN ... END -# ---disable_warnings -drop procedure if exists bug5307| ---enable_warnings -create procedure bug5307() -begin -end; set @x = 3| - -call bug5307()| -select @x| -drop procedure bug5307| - -# -# BUG#5258: Stored procedure modified date is 0000-00-00 -# (This was a design flaw) ---disable_warnings -drop procedure if exists bug5258| ---enable_warnings -create procedure bug5258() -begin -end| - ---disable_warnings -drop procedure if exists bug5258_aux| ---enable_warnings -create procedure bug5258_aux() -begin - declare c, m char(19); - - select created,modified into c,m from mysql.proc where name = 'bug5258'; - if c = m then - select 'Ok'; - else - select c, m; - end if; -end| - -call bug5258_aux()| - -drop procedure bug5258| -drop procedure bug5258_aux| - -# -# BUG#4487: Stored procedure connection aborted if uninitialized char -# ---disable_warnings -drop function if exists bug4487| ---enable_warnings -create function bug4487() returns char -begin - declare v char; - return v; -end| - -select bug4487()| -drop function bug4487| - - -# -# BUG#4941: Stored procedure crash fetching null value into variable. -# ---disable_warnings -drop procedure if exists bug4941| ---enable_warnings ---disable_warnings -drop procedure if exists bug4941| ---enable_warnings -create procedure bug4941(out x int) -begin - declare c cursor for select i from t2 limit 1; - open c; - fetch c into x; - close c; -end| - -insert into t2 values (null, null, null)| -set @x = 42| -call bug4941(@x)| -select @x| -delete from t1| -drop procedure bug4941| - - -# -# BUG#3583: query cache doesn't work for stored procedures -# ---disable_warnings -drop procedure if exists bug3583| ---enable_warnings ---disable_warnings -drop procedure if exists bug3583| ---enable_warnings -create procedure bug3583() -begin - declare c int; - - select * from t1; - select count(*) into c from t1; - select c; -end| - -insert into t1 values ("x", 3), ("y", 5)| -set @x = @@query_cache_size| -set global query_cache_size = 10*1024*1024| - -flush status| -flush query cache| -show status like 'Qcache_hits'| -call bug3583()| -show status like 'Qcache_hits'| -call bug3583()| -call bug3583()| -show status like 'Qcache_hits'| - -set global query_cache_size = @x| -flush status| -flush query cache| -delete from t1| -drop procedure bug3583| - -# -# BUG#4905: Stored procedure doesn't clear for "Rows affected" -# ---disable_warnings -drop procedure if exists bug4905| ---enable_warnings - -create table t3 (s1 int,primary key (s1))| - ---disable_warnings -drop procedure if exists bug4905| ---enable_warnings -create procedure bug4905() -begin - declare v int; - declare continue handler for sqlstate '23000' set v = 5; - - insert into t3 values (1); -end| - -call bug4905()| -select row_count()| -call bug4905()| -select row_count()| -call bug4905()| -select row_count()| -select * from t3| - -drop procedure bug4905| -drop table t3| - -# -# BUG#6022: Stored procedure shutdown problem with self-calling function. -# - ---disable_parsing # until we implement support for recursive stored functions. ---disable_warnings -drop function if exists bug6022| ---enable_warnings - ---disable_warnings -drop function if exists bug6022| ---enable_warnings -create function bug6022(x int) returns int -begin - if x < 0 then - return 0; - else - return bug6022(x-1); - end if; -end| - -select bug6022(5)| -drop function bug6022| ---enable_parsing - -# -# BUG#6029: Stored procedure specific handlers should have priority -# ---disable_warnings -drop procedure if exists bug6029| ---enable_warnings - ---disable_warnings -drop procedure if exists bug6029| ---enable_warnings -create procedure bug6029() -begin - declare exit handler for 1136 select '1136'; - declare exit handler for sqlstate '23000' select 'sqlstate 23000'; - declare continue handler for sqlexception select 'sqlexception'; - - insert into t3 values (1); - insert into t3 values (1,2); -end| - -create table t3 (s1 int, primary key (s1))| -insert into t3 values (1)| -call bug6029()| -delete from t3| -call bug6029()| - -drop procedure bug6029| -drop table t3| - -# -# BUG#8540: Local variable overrides an alias -# ---disable_warnings -drop procedure if exists bug8540| ---enable_warnings - -create procedure bug8540() -begin - declare x int default 1; - select x as y, x+0 as z; -end| - -call bug8540()| -drop procedure bug8540| - -# -# BUG#6642: Stored procedure crash if expression with set function -# -create table t3 (s1 int)| - ---disable_warnings -drop procedure if exists bug6642| ---enable_warnings - -create procedure bug6642() - select abs(count(s1)) from t3| - -call bug6642()| -call bug6642()| -drop procedure bug6642| - -# -# BUG#7013: Stored procedure crash if group by ... with rollup -# -insert into t3 values (0),(1)| ---disable_warnings -drop procedure if exists bug7013| ---enable_warnings -create procedure bug7013() - select s1,count(s1) from t3 group by s1 with rollup| -call bug7013()| -call bug7013()| -drop procedure bug7013| - -# -# BUG#7743: 'Lost connection to MySQL server during query' on Stored Procedure -# ---disable_warnings -drop table if exists t4| ---enable_warnings -create table t4 ( - a mediumint(8) unsigned not null auto_increment, - b smallint(5) unsigned not null, - c char(32) not null, - primary key (a) -) engine=myisam default charset=latin1| -insert into t4 values (1, 2, 'oneword')| -insert into t4 values (2, 2, 'anotherword')| - ---disable_warnings -drop procedure if exists bug7743| ---enable_warnings -create procedure bug7743 ( searchstring char(28) ) -begin - declare var mediumint(8) unsigned; - select a into var from t4 where b = 2 and c = binary searchstring limit 1; - select var; -end| - -call bug7743("oneword")| -call bug7743("OneWord")| -call bug7743("anotherword")| -call bug7743("AnotherWord")| -drop procedure bug7743| -drop table t4| - -# -# BUG#7992: SELECT .. INTO variable .. within Stored Procedure crashes -# the server -# -delete from t3| -insert into t3 values(1)| -drop procedure if exists bug7992_1| -drop procedure if exists bug7992_2| -create procedure bug7992_1() -begin - declare i int; - select max(s1)+1 into i from t3; -end| -create procedure bug7992_2() - insert into t3 (s1) select max(t4.s1)+1 from t3 as t4| - -call bug7992_1()| -call bug7992_1()| -call bug7992_2()| -call bug7992_2()| - -drop procedure bug7992_1| -drop procedure bug7992_2| -drop table t3| - -# -# BUG#8116: calling simple stored procedure twice in a row results -# in server crash -# -create table t3 ( userid bigint(20) not null default 0 )| - ---disable_warnings -drop procedure if exists bug8116| ---enable_warnings -create procedure bug8116(in _userid int) - select * from t3 where userid = _userid| - -call bug8116(42)| -call bug8116(42)| -drop procedure bug8116| -drop table t3| - -# -# BUG#6857: current_time() in STORED PROCEDURES -# ---disable_warnings -drop procedure if exists bug6857| ---enable_warnings -create procedure bug6857(counter int) -begin - declare t0, t1 int; - declare plus bool default 0; - - set t0 = current_time(); - while counter > 0 do - set counter = counter - 1; - end while; - set t1 = current_time(); - if t1 > t0 then - set plus = 1; - end if; - select plus; -end| - -# QQ: This is currently disabled. Not only does it slow down a normal test -# run, it makes running with valgrind (or similar tools) extremely -# painful. -# Make sure this takes at least one second on all machines in all builds. -# 30000 makes it about 3 seconds on an old 1.1GHz linux. -#call bug6857(300000)| - -drop procedure bug6857| - -# -# BUG#8757: Stored Procedures: Scope of Begin and End Statements do not -# work properly. ---disable_warnings -drop procedure if exists bug8757| ---enable_warnings -create procedure bug8757() -begin - declare x int; - declare c1 cursor for select data from t1 limit 1; - - begin - declare y int; - declare c2 cursor for select i from t2 limit 1; - - open c2; - fetch c2 into y; - close c2; - select 2,y; - end; - open c1; - fetch c1 into x; - close c1; - select 1,x; -end| - -delete from t1| -delete from t2| -insert into t1 values ("x", 1)| -insert into t2 values ("y", 2, 0.0)| - -call bug8757()| - -delete from t1| -delete from t2| -drop procedure bug8757| - - -# -# BUG#8762: Stored Procedures: Inconsistent behavior -# of DROP PROCEDURE IF EXISTS statement. ---disable_warnings -drop procedure if exists bug8762| ---enable_warnings -# Doesn't exist -drop procedure if exists bug8762; create procedure bug8762() begin end| -# Does exist -drop procedure if exists bug8762; create procedure bug8762() begin end| -drop procedure bug8762| - - -# -# BUG#5240: Stored procedure crash if function has cursor declaration -# ---disable_warnings -drop function if exists bug5240| ---enable_warnings -create function bug5240 () returns int -begin - declare x int; - declare c cursor for select data from t1 limit 1; - - open c; - fetch c into x; - close c; - return x; -end| - -delete from t1| -insert into t1 values ("answer", 42)| -select id, bug5240() from t1| -drop function bug5240| - -# -# BUG#5278: Stored procedure packets out of order if SET PASSWORD. -# ---disable_warnings -drop function if exists bug5278| ---enable_warnings -create function bug5278 () returns char -begin - SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass'); - return 'okay'; -end| - ---error 1133 -select bug5278()| ---error 1133 -select bug5278()| -drop function bug5278| - -# -# BUG#7992: rolling back temporary Item tree changes in SP -# ---disable_warnings -drop procedure if exists p1| ---enable_warnings -create table t3(id int)| -insert into t3 values(1)| -create procedure bug7992() -begin - declare i int; - select max(id)+1 into i from t3; -end| - -call bug7992()| -call bug7992()| -drop procedure bug7992| -drop table t3| -delimiter ;| - -# -# BUG#8849: problem with insert statement with table alias's -# -# Rolling back changes to AND/OR structure of ON and WHERE clauses in SP -# - -delimiter |; -create table t3 ( - lpitnumber int(11) default null, - lrecordtype int(11) default null -)| - -create table t4 ( - lbsiid int(11) not null default '0', - ltradingmodeid int(11) not null default '0', - ltradingareaid int(11) not null default '0', - csellingprice decimal(19,4) default null, - primary key (lbsiid,ltradingmodeid,ltradingareaid) -)| - -create table t5 ( - lbsiid int(11) not null default '0', - ltradingareaid int(11) not null default '0', - primary key (lbsiid,ltradingareaid) -)| - ---disable_warnings -drop procedure if exists bug8849| ---enable_warnings -create procedure bug8849() -begin - insert into t5 - ( - t5.lbsiid, - t5.ltradingareaid - ) - select distinct t3.lpitnumber, t4.ltradingareaid - from - t4 join t3 on - t3.lpitnumber = t4.lbsiid - and t3.lrecordtype = 1 - left join t4 as price01 on - price01.lbsiid = t4.lbsiid and - price01.ltradingmodeid = 1 and - t4.ltradingareaid = price01.ltradingareaid; -end| - -call bug8849()| -call bug8849()| -call bug8849()| -drop procedure bug8849| -drop tables t3,t4,t5| - -# -# BUG#8937: Stored Procedure: AVG() works as SUM() in SELECT ... INTO statement -# ---disable_warnings -drop procedure if exists bug8937| ---enable_warnings -create procedure bug8937() -begin - declare s,x,y,z int; - declare a float; - - select sum(data),avg(data),min(data),max(data) into s,x,y,z from t1; - select s,x,y,z; - select avg(data) into a from t1; - select a; -end| - -delete from t1| -insert into t1 (data) values (1), (2), (3), (4), (6)| -call bug8937()| - -drop procedure bug8937| -delete from t1| - - -# -# BUG#6900: Stored procedure inner handler ignored -# BUG#9074: STORED PROC: The scope of every handler declared is not -# properly applied -# ---disable_warnings -drop procedure if exists bug6900| -drop procedure if exists bug9074| -drop procedure if exists bug6900_9074| ---enable_warnings - -create table t3 (w char unique, x char)| -insert into t3 values ('a', 'b')| - -create procedure bug6900() -begin - declare exit handler for sqlexception select '1'; - - begin - declare exit handler for sqlexception select '2'; - - insert into t3 values ('x', 'y', 'z'); - end; -end| - -create procedure bug9074() -begin - declare x1, x2, x3, x4, x5, x6 int default 0; - - begin - declare continue handler for sqlstate '23000' set x5 = 1; - - insert into t3 values ('a', 'b'); - set x6 = 1; - end; - - begin1_label: - begin - declare continue handler for sqlstate '23000' set x1 = 1; - - insert into t3 values ('a', 'b'); - set x2 = 1; - - begin2_label: - begin - declare exit handler for sqlstate '23000' set x3 = 1; - - set x4= 1; - insert into t3 values ('a','b'); - set x4= 0; - end begin2_label; - end begin1_label; - - select x1, x2, x3, x4, x5, x6; -end| - -create procedure bug6900_9074(z int) -begin - declare exit handler for sqlstate '23000' select '23000'; - - begin - declare exit handler for sqlexception select 'sqlexception'; - - if z = 1 then - insert into t3 values ('a', 'b'); - else - insert into t3 values ('x', 'y', 'z'); - end if; - end; -end| - -call bug6900()| -call bug9074()| -call bug6900_9074(0)| -call bug6900_9074(1)| - -drop procedure bug6900| -drop procedure bug9074| -drop procedure bug6900_9074| -drop table t3| - - -# -# BUG#7185: Stored procedure crash if identifier is AVG -# ---disable_warnings -drop procedure if exists avg| ---enable_warnings -create procedure avg () -begin -end| - -call avg ()| -drop procedure avg| - - -# -# BUG#6129: Stored procedure won't display @@sql_mode value -# ---disable_warnings -drop procedure if exists bug6129| ---enable_warnings -set @old_mode= @@sql_mode; -set @@sql_mode= "ERROR_FOR_DIVISION_BY_ZERO"; -create procedure bug6129() - select @@sql_mode| -call bug6129()| -set @@sql_mode= "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO"| -call bug6129()| -set @@sql_mode= "NO_ZERO_IN_DATE"| -call bug6129()| -set @@sql_mode=@old_mode; - -drop procedure bug6129| - - -# -# BUG#9856: Stored procedures: crash if handler for sqlexception, not found -# ---disable_warnings -drop procedure if exists bug9856| ---enable_warnings -create procedure bug9856() -begin - declare v int; - declare c cursor for select data from t1; - declare exit handler for sqlexception, not found select '16'; - - open c; - fetch c into v; - select v; -end| - -delete from t1| -call bug9856()| -call bug9856()| -drop procedure bug9856| - - -# -# BUG##9674: Stored Procs: Using declared vars in algebric operation causes -# system crash. -# ---disable_warnings -drop procedure if exists bug9674_1| -drop procedure if exists bug9674_2| ---enable_warnings -create procedure bug9674_1(out arg int) -begin - declare temp_in1 int default 0; - declare temp_fl1 int default 0; - - set temp_in1 = 100; - set temp_fl1 = temp_in1/10; - set arg = temp_fl1; -end| - -create procedure bug9674_2() -begin - declare v int default 100; - - select v/10; -end| - -call bug9674_1(@sptmp)| -call bug9674_1(@sptmp)| -select @sptmp| -call bug9674_2()| -call bug9674_2()| -drop procedure bug9674_1| -drop procedure bug9674_2| - - -# -# BUG#9598: stored procedure call within stored procedure overwrites IN variable -# ---disable_warnings -drop procedure if exists bug9598_1| -drop procedure if exists bug9598_2| ---enable_warnings -create procedure bug9598_1(in var_1 char(16), - out var_2 integer, out var_3 integer) -begin - set var_2 = 50; - set var_3 = 60; -end| - -create procedure bug9598_2(in v1 char(16), - in v2 integer, - in v3 integer, - in v4 integer, - in v5 integer) -begin - select v1,v2,v3,v4,v5; - call bug9598_1(v1,@tmp1,@tmp2); - select v1,v2,v3,v4,v5; -end| - -call bug9598_2('Test',2,3,4,5)| -select @tmp1, @tmp2| - -drop procedure bug9598_1| -drop procedure bug9598_2| - - -# -# BUG#9902: Crash with simple stored function using user defined variables -# ---disable_warnings -drop procedure if exists bug9902| ---enable_warnings -create function bug9902() returns int(11) -begin - set @x = @x + 1; - return @x; -end| - -set @qcs1 = @@query_cache_size| -set global query_cache_size = 100000| -set @x = 1| -insert into t1 values ("qc", 42)| -select bug9902() from t1| -select bug9902() from t1| -select @x| - -set global query_cache_size = @qcs1| -delete from t1| -drop function bug9902| - - -# -# BUG#9102: Stored proccedures: function which returns blob causes crash -# ---disable_warnings -drop function if exists bug9102| ---enable_warnings -create function bug9102() returns blob return 'a'| -select bug9102()| -drop function bug9102| - - -# -# BUG#7648: Stored procedure crash when invoking a function that returns a bit -# ---disable_warnings -drop function if exists bug7648| ---enable_warnings -create function bug7648() returns bit(8) return 'a'| -select bug7648()| -drop function bug7648| - - -# -# BUG#9775: crash if create function that returns enum or set -# ---disable_warnings -drop function if exists bug9775| ---enable_warnings -create function bug9775(v1 char(1)) returns enum('a','b') return v1| -select bug9775('a'),bug9775('b'),bug9775('c')| -drop function bug9775| -create function bug9775(v1 int) returns enum('a','b') return v1| -select bug9775(1),bug9775(2),bug9775(3)| -drop function bug9775| - -create function bug9775(v1 char(1)) returns set('a','b') return v1| -select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')| -drop function bug9775| -create function bug9775(v1 int) returns set('a','b') return v1| -select bug9775(1),bug9775(2),bug9775(3),bug9775(4)| -drop function bug9775| - - -# -# BUG#8861: If Return is a YEAR data type, value is not shown in year format -# ---disable_warnings -drop function if exists bug8861| ---enable_warnings -create function bug8861(v1 int) returns year return v1| -select bug8861(05)| -set @x = bug8861(05)| -select @x| -drop function bug8861| - - -# -# BUG#9004: Inconsistent behaviour of SP re. warnings -# ---disable_warnings -drop procedure if exists bug9004_1| -drop procedure if exists bug9004_2| ---enable_warnings -create procedure bug9004_1(x char(16)) -begin - insert into t1 values (x, 42); - insert into t1 values (x, 17); -end| -create procedure bug9004_2(x char(16)) - call bug9004_1(x)| - -# Truncation warnings expected... -call bug9004_1('12345678901234567')| -call bug9004_2('12345678901234567890')| - -delete from t1| -drop procedure bug9004_1| -drop procedure bug9004_2| - -# -# BUG#7293: Stored procedure crash with soundex -# ---disable_warnings -drop procedure if exists bug7293| ---enable_warnings -insert into t1 values ('secret', 0)| -create procedure bug7293(p1 varchar(100)) -begin - if exists (select id from t1 where soundex(p1)=soundex(id)) then - select 'yes'; - end if; -end;| -call bug7293('secret')| -call bug7293 ('secrete')| -drop procedure bug7293| -delete from t1| - - -# -# BUG#9841: Unexpected read lock when trying to update a view in a -# stored procedure -# ---disable_warnings -drop procedure if exists bug9841| -drop view if exists v1| ---enable_warnings - -create view v1 as select * from t1, t2 where id = s| -create procedure bug9841 () - update v1 set data = 10| -call bug9841()| - -drop view v1| -drop procedure bug9841| - - -# -# BUG#5963 subqueries in SET/IF -# ---disable_warnings -drop procedure if exists bug5963| ---enable_warnings - -create procedure bug5963_1 () begin declare v int; set v = (select s1 from t3); select v; end;| -create table t3 (s1 int)| -insert into t3 values (5)| -call bug5963_1()| -call bug5963_1()| -drop procedure bug5963_1| -drop table t3| - -create procedure bug5963_2 (cfk_value int) -begin - if cfk_value in (select cpk from t3) then - set @x = 5; - end if; - end; -| -create table t3 (cpk int)| -insert into t3 values (1)| -call bug5963_2(1)| -call bug5963_2(1)| -drop procedure bug5963_2| -drop table t3| - - -# -# BUG#9559: Functions: Numeric Operations using -ve value gives incorrect -# results. -# ---disable_warnings -drop function if exists bug9559| ---enable_warnings -create function bug9559() - returns int -begin - set @y = -6/2; - return @y; -end| - -select bug9559()| - -drop function bug9559| - - -# -# BUG#10961: Stored procedures: crash if select * from dual -# ---disable_warnings -drop procedure if exists bug10961| ---enable_warnings -# "select * from dual" results in an error, so the cursor will not open -create procedure bug10961() -begin - declare v char; - declare x int; - declare c cursor for select * from dual; - declare continue handler for sqlexception select x; - - set x = 1; - open c; - set x = 2; - fetch c into v; - set x = 3; - close c; -end| - -call bug10961()| -call bug10961()| - -drop procedure bug10961| - -# -# BUG #6866: Second call of a stored procedure using a view with on expressions -# - ---disable_warnings -DROP PROCEDURE IF EXISTS bug6866| ---enable_warnings - -DROP VIEW IF EXISTS tv| -DROP TABLE IF EXISTS tt1,tt2,tt3| - -CREATE TABLE tt1 (a1 int, a2 int, a3 int, data varchar(10))| -CREATE TABLE tt2 (a2 int, data2 varchar(10))| -CREATE TABLE tt3 (a3 int, data3 varchar(10))| - -INSERT INTO tt1 VALUES (1, 1, 4, 'xx')| - -INSERT INTO tt2 VALUES (1, 'a')| -INSERT INTO tt2 VALUES (2, 'b')| -INSERT INTO tt2 VALUES (3, 'c')| - -INSERT INTO tt3 VALUES (4, 'd')| -INSERT INTO tt3 VALUES (5, 'e')| -INSERT INTO tt3 VALUES (6, 'f')| - -CREATE VIEW tv AS -SELECT tt1.*, tt2.data2, tt3.data3 - FROM tt1 INNER JOIN tt2 ON tt1.a2 = tt2.a2 - LEFT JOIN tt3 ON tt1.a3 = tt3.a3 - ORDER BY tt1.a1, tt2.a2, tt3.a3| - -CREATE PROCEDURE bug6866 (_a1 int) -BEGIN -SELECT * FROM tv WHERE a1 = _a1; -END| - -CALL bug6866(1)| -CALL bug6866(1)| -CALL bug6866(1)| - -DROP PROCEDURE bug6866; - -DROP VIEW tv| -DROP TABLE tt1, tt2, tt3| - -# -# BUG#10136: items cleunup -# ---disable_warnings -DROP PROCEDURE IF EXISTS bug10136| ---enable_warnings -create table t3 ( name char(5) not null primary key, val float not null)| -insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)| -create procedure bug10136() -begin - declare done int default 3; - - repeat - select * from t3; - set done = done - 1; - until done <= 0 end repeat; - -end| -call bug10136()| -call bug10136()| -call bug10136()| -drop procedure bug10136| -drop table t3| - -# -# BUG#11529: crash server after use stored procedure -# ---disable_warnings -drop procedure if exists bug11529| ---enable_warnings -create procedure bug11529() -begin - declare c cursor for select id, data from t1 where data in (10,13); - - open c; - begin - declare vid char(16); - declare vdata int; - declare exit handler for not found begin end; - - while true do - fetch c into vid, vdata; - end while; - end; - close c; -end| - -insert into t1 values - ('Name1', 10), - ('Name2', 11), - ('Name3', 12), - ('Name4', 13), - ('Name5', 14)| - -call bug11529()| -call bug11529()| -delete from t1| -drop procedure bug11529| - - -# -# BUG#6063: Stored procedure labels are subject to restrictions (partial) -# BUG#7088: Stored procedures: labels won't work if character set is utf8 -# ---disable_warnings -drop procedure if exists bug6063| -drop procedure if exists bug7088_1| -drop procedure if exists bug7088_2| ---enable_warnings - ---disable_parsing # temporarily disabled until Bar fixes BUG#11986 -create procedure bug6063() - lâbel: begin end| -call bug6063()| -# QQ Known bug: this will not show the label correctly. -show create procedure bug6063| - -set character set utf8| -create procedure bug7088_1() - label1: begin end label1| -create procedure bug7088_2() - läbel1: begin end| -call bug7088_1()| -call bug7088_2()| -set character set default| -show create procedure bug7088_1| -show create procedure bug7088_2| - -drop procedure bug6063| -drop procedure bug7088_1| -drop procedure bug7088_2| ---enable_parsing - -# -# BUG#9565: "Wrong locking in stored procedure if a sub-sequent procedure -# is called". -# ---disable_warnings -drop procedure if exists bug9565_sub| -drop procedure if exists bug9565| ---enable_warnings -create procedure bug9565_sub() -begin - select * from t1; -end| -create procedure bug9565() -begin - insert into t1 values ("one", 1); - call bug9565_sub(); -end| -call bug9565()| -delete from t1| -drop procedure bug9565_sub| -drop procedure bug9565| - - -# -# BUG#9538: SProc: Creation fails if we try to SET system variable -# using @@var_name in proc -# ---disable_warnings -drop procedure if exists bug9538| ---enable_warnings -create procedure bug9538() - set @@sort_buffer_size = 1000000| - -set @x = @@sort_buffer_size| -set @@sort_buffer_size = 2000000| -select @@sort_buffer_size| -call bug9538()| -select @@sort_buffer_size| -set @@sort_buffer_size = @x| - -drop procedure bug9538| - - -# -# BUG#8692: Cursor fetch of empty string -# ---disable_warnings -drop procedure if exists bug8692| ---enable_warnings -create table t3 (c1 varchar(5), c2 char(5), c3 enum('one','two'), c4 text, c5 blob, c6 char(5), c7 varchar(5))| -insert into t3 values ('', '', '', '', '', '', NULL)| - -create procedure bug8692() -begin - declare v1 VARCHAR(10); - declare v2 VARCHAR(10); - declare v3 VARCHAR(10); - declare v4 VARCHAR(10); - declare v5 VARCHAR(10); - declare v6 VARCHAR(10); - declare v7 VARCHAR(10); - declare c8692 cursor for select c1,c2,c3,c4,c5,c6,c7 from t3; - open c8692; - fetch c8692 into v1,v2,v3,v4,v5,v6,v7; - select v1, v2, v3, v4, v5, v6, v7; -end| - -call bug8692()| -drop procedure bug8692| -drop table t3| - -# -# Bug#10055 "Using stored function with information_schema causes empty -# result set" -# ---disable_warnings -drop function if exists bug10055| ---enable_warnings -create function bug10055(v char(255)) returns char(255) return lower(v)| -# This select should not crash server and should return all fields in t1 -select t.column_name, bug10055(t.column_name) -from information_schema.columns as t -where t.table_schema = 'test' and t.table_name = 't1'| -drop function bug10055| - -# -# Bug #12297 "SP crashes the server if data inserted inside a lon loop" -# The test for memleak bug, so actually there is no way to test it -# from the suite. The test below could be used to check SP memory -# consumption by passing large input parameter. -# - ---disable_warnings -drop procedure if exists bug12297| ---enable_warnings - -create procedure bug12297(lim int) -begin - set @x = 0; - repeat - insert into t1(id,data) - values('aa', @x); - set @x = @x + 1; - until @x >= lim - end repeat; -end| - -call bug12297(10)| -drop procedure bug12297| - -# -# Bug #11247 "Stored procedures: Function calls in long loops leak memory" -# One more memleak bug test. One could use this test to check that the memory -# isn't leaking by increasing the input value for p_bug11247. -# - ---disable_warnings -drop function if exists f_bug11247| -drop procedure if exists p_bug11247| ---enable_warnings - -create function f_bug11247(param int) - returns int -return param + 1| - -create procedure p_bug11247(lim int) -begin - declare v int default 0; - - while v < lim do - set v= f_bug11247(v); - end while; -end| - -call p_bug11247(10)| -drop function f_bug11247| -drop procedure p_bug11247| -# -# BUG#12168: "'DECLARE CONTINUE HANDLER FOR NOT FOUND ...' in conditional -# handled incorrectly" -# ---disable_warnings -drop procedure if exists bug12168| -drop table if exists t3, t4| ---enable_warnings - -create table t3 (a int)| -insert into t3 values (1),(2),(3),(4)| - -create table t4 (a int)| - -create procedure bug12168(arg1 char(1)) -begin - declare b, c integer; - if arg1 = 'a' then - begin - declare c1 cursor for select a from t3 where a % 2; - declare continue handler for not found set b = 1; - set b = 0; - open c1; - c1_repeat: repeat - fetch c1 into c; - if (b = 1) then - leave c1_repeat; - end if; - - insert into t4 values (c); - until b = 1 - end repeat; - end; - end if; - if arg1 = 'b' then - begin - declare c2 cursor for select a from t3 where not a % 2; - declare continue handler for not found set b = 1; - set b = 0; - open c2; - c2_repeat: repeat - fetch c2 into c; - if (b = 1) then - leave c2_repeat; - end if; - - insert into t4 values (c); - until b = 1 - end repeat; - end; - end if; -end| - -call bug12168('a')| -select * from t4| -truncate t4| -call bug12168('b')| -select * from t4| -truncate t4| -call bug12168('a')| -select * from t4| -truncate t4| -call bug12168('b')| -select * from t4| -truncate t4| -drop table t3, t4| -drop procedure if exists bug12168| - -# -# Bug #11333 "Stored Procedure: Memory blow up on repeated SELECT ... INTO -# query" -# One more memleak bug. Use the test to check memory consumption. -# - ---disable_warnings -drop table if exists t3| -drop procedure if exists bug11333| ---enable_warnings - -create table t3 (c1 char(128))| - -insert into t3 values - ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')| - - -create procedure bug11333(i int) -begin - declare tmp varchar(128); - set @x = 0; - repeat - select c1 into tmp from t3 - where c1 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; - set @x = @x + 1; - until @x >= i - end repeat; -end| - -call bug11333(10)| - -drop procedure bug11333| -drop table t3| - -# -# BUG#9048: Creating a function with char binary IN parameter fails -# ---disable_warnings -drop function if exists bug9048| ---enable_warnings -create function bug9048(f1 char binary) returns char binary -begin - set f1= concat( 'hello', f1 ); - return f1; -end| -drop function bug9048| - -# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type -# 'INOUT' parameter -# - ---disable_warnings -drop procedure if exists bug12849_1| ---enable_warnings -create procedure bug12849_1(inout x char) select x into x| -set @var='a'| -call bug12849_1(@var)| -select @var| -drop procedure bug12849_1| - ---disable_warnings -drop procedure if exists bug12849_2| ---enable_warnings -create procedure bug12849_2(inout foo varchar(15)) -begin -select concat(foo, foo) INTO foo; -end| -set @var='abcd'| -call bug12849_2(@var)| -select @var| -drop procedure bug12849_2| - -# -# BUG#13133: Local variables in stored procedures are not initialized correctly. -# ---disable_warnings -drop procedure if exists bug131333| -drop function if exists bug131333| ---enable_warnings -create procedure bug131333() -begin - begin - declare a int; - - select a; - set a = 1; - select a; - end; - begin - declare b int; - - select b; - end; -end| - -create function bug131333() - returns int -begin - begin - declare a int; - - set a = 1; - end; - begin - declare b int; - - return b; - end; -end| - -call bug131333()| -select bug131333()| - -drop procedure bug131333| -drop function bug131333| - -# -# BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get -# strange result -# ---disable_warnings -drop function if exists bug12379| -drop procedure if exists bug12379_1| -drop procedure if exists bug12379_2| -drop procedure if exists bug12379_3| -drop table if exists t3| ---enable_warnings - -create table t3 (c1 char(1) primary key not null)| - -create function bug12379() - returns integer -begin - insert into t3 values('X'); - insert into t3 values('X'); - return 0; -end| - -create procedure bug12379_1() -begin - declare exit handler for sqlexception select 42; - - select bug12379(); -END| -create procedure bug12379_2() -begin - declare exit handler for sqlexception begin end; - - select bug12379(); -end| -create procedure bug12379_3() -begin - select bug12379(); -end| - ---error 1062 -select bug12379()| -select 1| -call bug12379_1()| -select 2| -call bug12379_2()| -select 3| ---error 1062 -call bug12379_3()| -select 4| - -drop function bug12379| -drop procedure bug12379_1| -drop procedure bug12379_2| -drop procedure bug12379_3| -drop table t3| - -# -# Bug #13124 Stored Procedure using SELECT INTO crashes server -# - ---disable_warnings -drop procedure if exists bug13124| ---enable_warnings -create procedure bug13124() -begin - declare y integer; - set @x=y; -end| -call bug13124()| -drop procedure bug13124| - -# -# Bug #12979 Stored procedures: crash if inout decimal parameter -# - -# check NULL inout parameters processing - ---disable_warnings -drop procedure if exists bug12979_1| ---enable_warnings -create procedure bug12979_1(inout d decimal(5)) set d = d / 2| -set @bug12979_user_var = NULL| -call bug12979_1(@bug12979_user_var)| -drop procedure bug12979_1| - -# check NULL local variables processing - ---disable_warnings -drop procedure if exists bug12979_2| ---enable_warnings -create procedure bug12979_2() -begin -declare internal_var decimal(5); -set internal_var= internal_var / 2; -select internal_var; -end| -call bug12979_2()| -drop procedure bug12979_2| - - -# -# BUG#6127: Stored procedure handlers within handlers don't work -# ---disable_warnings -drop table if exists t3| -drop procedure if exists bug6127| ---enable_warnings -create table t3 (s1 int unique)| - -set @sm=@@sql_mode| -set sql_mode='traditional'| - -create procedure bug6127() -begin - declare continue handler for sqlstate '23000' - begin - declare continue handler for sqlstate '22003' - insert into t3 values (0); - - insert into t3 values (1000000000000000); - end; - - insert into t3 values (1); - insert into t3 values (1); -end| - -call bug6127()| -select * from t3| ---error ER_DUP_ENTRY -call bug6127()| -select * from t3| -set sql_mode=@sm| -drop table t3| -drop procedure bug6127| - - -# -# BUG#12589: Assert when creating temp. table from decimal stored procedure -# variable -# ---disable_warnings -drop procedure if exists bug12589_1| -drop procedure if exists bug12589_2| -drop procedure if exists bug12589_3| ---enable_warnings -create procedure bug12589_1() -begin - declare spv1 decimal(3,3); - set spv1= 123.456; - - set spv1 = 'test'; - create temporary table tm1 as select spv1; - show create table tm1; - drop temporary table tm1; -end| - -create procedure bug12589_2() -begin - declare spv1 decimal(6,3); - set spv1= 123.456; - - create temporary table tm1 as select spv1; - show create table tm1; - drop temporary table tm1; -end| - -create procedure bug12589_3() -begin - declare spv1 decimal(6,3); - set spv1= -123.456; - - create temporary table tm1 as select spv1; - show create table tm1; - drop temporary table tm1; -end| - -# Note: The type of the field will match the value, not the declared -# type of the variable. (This is a type checking issue which -# might be changed later.) - -# Warning expected from "set spv1 = 'test'", the value is set to decimal "0". -call bug12589_1()| -# No warnings here -call bug12589_2()| -call bug12589_3()| -drop procedure bug12589_1| -drop procedure bug12589_2| -drop procedure bug12589_3| - -# -# BUG#7049: Stored procedure CALL errors are ignored -# ---disable_warnings -drop table if exists t3| -drop procedure if exists bug7049_1| -drop procedure if exists bug7049_2| -drop procedure if exists bug7049_3| -drop procedure if exists bug7049_4| -drop function if exists bug7049_1| -drop function if exists bug7049_2| ---enable_warnings - -create table t3 ( x int unique )| - -create procedure bug7049_1() -begin - insert into t3 values (42); - insert into t3 values (42); -end| - -create procedure bug7049_2() -begin - declare exit handler for sqlexception - select 'Caught it' as 'Result'; - - call bug7049_1(); - select 'Missed it' as 'Result'; -end| - -create procedure bug7049_3() - call bug7049_1()| - -create procedure bug7049_4() -begin - declare exit handler for sqlexception - select 'Caught it' as 'Result'; - - call bug7049_3(); - select 'Missed it' as 'Result'; -end| - -create function bug7049_1() - returns int -begin - insert into t3 values (42); - insert into t3 values (42); - return 42; -end| - -create function bug7049_2() - returns int -begin - declare x int default 0; - declare continue handler for sqlexception - set x = 1; - - set x = bug7049_1(); - return x; -end| - -call bug7049_2()| -select * from t3| -delete from t3| -call bug7049_4()| -select * from t3| -select bug7049_2()| - -drop table t3| -drop procedure bug7049_1| -drop procedure bug7049_2| -drop procedure bug7049_3| -drop procedure bug7049_4| -drop function bug7049_1| -drop function bug7049_2| - - -# -# BUG#13941: replace() string fuction behaves badly inside stored procedure -# (BUG#13914: IFNULL is returning garbage in stored procedure) -# ---disable_warnings -drop function if exists bug13941| -drop procedure if exists bug13941| ---enable_warnings - -create function bug13941(p_input_str text) - returns text -begin - declare p_output_str text; - - set p_output_str = p_input_str; - - set p_output_str = replace(p_output_str, 'xyzzy', 'plugh'); - set p_output_str = replace(p_output_str, 'test', 'prova'); - set p_output_str = replace(p_output_str, 'this', 'questo'); - set p_output_str = replace(p_output_str, ' a ', 'una '); - set p_output_str = replace(p_output_str, 'is', ''); - - return p_output_str; -end| - -create procedure bug13941(out sout varchar(128)) -begin - set sout = 'Local'; - set sout = ifnull(sout, 'DEF'); -end| - -# Note: The bug showed different behaviour in different types of builds, -# giving garbage results in some, and seemingly working in others. -# Running with valgrind (or purify) is the safe way to check that it's -# really working correctly. -select bug13941('this is a test')| -call bug13941(@a)| -select @a| - -drop function bug13941| -drop procedure bug13941| - - -# -# BUG#13095: Cannot create VIEWs in prepared statements -# - -delimiter ;| - ---disable_warnings -DROP PROCEDURE IF EXISTS bug13095; -DROP TABLE IF EXISTS bug13095_t1; -DROP VIEW IF EXISTS bug13095_v1; ---enable_warnings - -delimiter |; - -CREATE PROCEDURE bug13095(tbl_name varchar(32)) -BEGIN - SET @str = - CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))"); - SELECT @str; - PREPARE stmt FROM @str; - EXECUTE stmt; - - SET @str = - CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" ); - SELECT @str; - PREPARE stmt FROM @str; - EXECUTE stmt; - - SET @str = - CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name); - SELECT @str; - PREPARE stmt FROM @str; - EXECUTE stmt; - - SELECT * FROM bug13095_v1; - - SET @str = - "DROP VIEW bug13095_v1"; - SELECT @str; - PREPARE stmt FROM @str; - EXECUTE stmt; -END| - -delimiter ;| - -CALL bug13095('bug13095_t1'); - ---disable_warnings -DROP PROCEDURE IF EXISTS bug13095; -DROP VIEW IF EXISTS bug13095_v1; -DROP TABLE IF EXISTS bug13095_t1; ---enable_warnings - -delimiter |; - -# -# BUG#14210: "Simple query with > operator on large table gives server -# crash" -# Check that cursors work in case when HEAP tables are converted to -# MyISAM -# ---disable_warnings -drop procedure if exists bug14210| ---enable_warnings -set @@session.max_heap_table_size=16384| -select @@session.max_heap_table_size| -# To trigger the memory corruption the original table must be InnoDB. -# No harm if it's not, so don't warn if the suite is run with --skip-innodb ---disable_warnings -create table t3 (a char(255)) engine=InnoDB| ---enable_warnings -create procedure bug14210_fill_table() -begin - declare table_size, max_table_size int default 0; - select @@session.max_heap_table_size into max_table_size; - delete from t3; - insert into t3 (a) values (repeat('a', 255)); - repeat - insert into t3 select a from t3; - select count(*)*255 from t3 into table_size; - until table_size > max_table_size*2 end repeat; -end| -call bug14210_fill_table()| -drop procedure bug14210_fill_table| -create table t4 like t3| - -create procedure bug14210() -begin - declare a char(255); - declare done int default 0; - declare c cursor for select * from t3; - declare continue handler for sqlstate '02000' set done = 1; - open c; - repeat - fetch c into a; - if not done then - insert into t4 values (upper(a)); - end if; - until done end repeat; - close c; -end| -call bug14210()| -select count(*) from t4| - -drop table t3, t4| -drop procedure bug14210| -set @@session.max_heap_table_size=default| - - -# -# BUG#1473: Dumping of stored functions seems to cause corruption in -# the function body -# ---disable_warnings -drop function if exists bug14723| -drop procedure if exists bug14723| ---enable_warnings - -delimiter ;;| -/*!50003 create function bug14723() - returns bigint(20) -main_loop: begin - return 42; -end */;; -show create function bug14723;; -select bug14723();; - -/*!50003 create procedure bug14723() -main_loop: begin - select 42; -end */;; -show create procedure bug14723;; -call bug14723();; - -delimiter |;; - -drop function bug14723| -drop procedure bug14723| - -# -# Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0" -# Check that when fetching from a cursor, COUNT(*) works properly. -# -create procedure bug14845() -begin - declare a char(255); - declare done int default 0; - declare c cursor for select count(*) from t1 where 1 = 0; - declare continue handler for sqlstate '02000' set done = 1; - open c; - repeat - fetch c into a; - if not done then - select a; - end if; - until done end repeat; - close c; -end| -call bug14845()| -drop procedure bug14845| - -# -# BUG#13549 "Server crash with nested stored procedures". -# Server should not crash when during execution of stored procedure -# we have to parse trigger/function definition and this new trigger/ -# function has more local variables declared than invoking stored -# procedure and last of these variables is used in argument of NOT -# operator. -# ---disable_warnings -drop procedure if exists bug13549_1| -drop procedure if exists bug13549_2| ---enable_warnings -CREATE PROCEDURE `bug13549_2`() -begin - call bug13549_1(); -end| -CREATE PROCEDURE `bug13549_1`() -begin - declare done int default 0; - set done= not done; -end| -CALL bug13549_2()| -drop procedure bug13549_2| -drop procedure bug13549_1| - -# -# BUG#10100: function (and stored procedure?) recursivity problem -# ---disable_warnings -drop function if exists bug10100f| -drop procedure if exists bug10100p| -drop procedure if exists bug10100t| -drop procedure if exists bug10100pt| -drop procedure if exists bug10100pv| -drop procedure if exists bug10100pd| -drop procedure if exists bug10100pc| ---enable_warnings -# routines with simple recursion -create function bug10100f(prm int) returns int -begin - if prm > 1 then - return prm * bug10100f(prm - 1); - end if; - return 1; -end| -create procedure bug10100p(prm int, inout res int) -begin - set res = res * prm; - if prm > 1 then - call bug10100p(prm - 1, res); - end if; -end| -create procedure bug10100t(prm int) -begin - declare res int; - set res = 1; - call bug10100p(prm, res); - select res; -end| - -# a procedure which use tables and recursion -create table t3 (a int)| -insert into t3 values (0)| -create view v1 as select a from t3; -create procedure bug10100pt(level int, lim int) -begin - if level < lim then - update t3 set a=level; - FLUSH TABLES; - call bug10100pt(level+1, lim); - else - select * from t3; - end if; -end| -# view & recursion -create procedure bug10100pv(level int, lim int) -begin - if level < lim then - update v1 set a=level; - FLUSH TABLES; - call bug10100pv(level+1, lim); - else - select * from v1; - end if; -end| -# dynamic sql & recursion -prepare stmt2 from "select * from t3;"; -create procedure bug10100pd(level int, lim int) -begin - if level < lim then - select level; - prepare stmt1 from "update t3 set a=a+2"; - execute stmt1; - FLUSH TABLES; - execute stmt1; - FLUSH TABLES; - execute stmt1; - FLUSH TABLES; - deallocate prepare stmt1; - execute stmt2; - select * from t3; - call bug10100pd(level+1, lim); - else - execute stmt2; - end if; -end| -# cursor & recursion -create procedure bug10100pc(level int, lim int) -begin - declare lv int; - declare c cursor for select a from t3; - open c; - if level < lim then - select level; - fetch c into lv; - select lv; - update t3 set a=level+lv; - FLUSH TABLES; - call bug10100pc(level+1, lim); - else - select * from t3; - end if; - close c; -end| - -set @@max_sp_recursion_depth=4| -select @@max_sp_recursion_depth| --- error ER_SP_NO_RECURSION -select bug10100f(3)| --- error ER_SP_NO_RECURSION -select bug10100f(6)| -call bug10100t(5)| -call bug10100pt(1,5)| -call bug10100pv(1,5)| -update t3 set a=1| -call bug10100pd(1,5)| -select * from t3| -update t3 set a=1| -call bug10100pc(1,5)| -select * from t3| -set @@max_sp_recursion_depth=0| -select @@max_sp_recursion_depth| --- error ER_SP_NO_RECURSION -select bug10100f(5)| --- error ER_SP_RECURSION_LIMIT -call bug10100t(5)| - -#end of the stack checking -set @@max_sp_recursion_depth=255| -set @var=1| -#disable log because error about stack overrun contains numbers which -#depend on a system --- disable_result_log --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100p(255, @var)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pt(1,255)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pv(1,255)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pd(1,255)| --- error ER_STACK_OVERRUN_NEED_MORE -call bug10100pc(1,255)| --- enable_result_log -set @@max_sp_recursion_depth=0| - -deallocate prepare stmt2| - -drop function bug10100f| -drop procedure bug10100p| -drop procedure bug10100t| -drop procedure bug10100pt| -drop procedure bug10100pv| -drop procedure bug10100pd| -drop procedure bug10100pc| -drop view v1| - -# -# BUG#13729: Stored procedures: packet error after exception handled -# ---disable_warnings -drop procedure if exists bug13729| -drop table if exists t3| ---enable_warnings - -create table t3 (s1 int, primary key (s1))| - -insert into t3 values (1),(2)| - -create procedure bug13729() -begin - declare continue handler for sqlexception select 55; - - update t3 set s1 = 1; -end| - -call bug13729()| -# Used to cause Packets out of order -select * from t3| - -drop procedure bug13729| -drop table t3| - -# -# BUG#14643: Stored Procedure: Continuing after failed var. initialization -# crashes server. -# ---disable_warnings -drop procedure if exists bug14643_1| -drop procedure if exists bug14643_2| ---enable_warnings - -create procedure bug14643_1() -begin - declare continue handler for sqlexception select 'boo' as 'Handler'; - - begin - declare v int default undefined_var; - - if v = 1 then - select 1; - else - select v, isnull(v); - end if; - end; -end| - -create procedure bug14643_2() -begin - declare continue handler for sqlexception select 'boo' as 'Handler'; - - case undefined_var - when 1 then - select 1; - else - select 2; - end case; - - select undefined_var; -end| - -call bug14643_1()| -call bug14643_2()| - -drop procedure bug14643_1| -drop procedure bug14643_2| - -# -# BUG#14304: auto_increment field incorrect set in SP -# ---disable_warnings -drop procedure if exists bug14304| -drop table if exists t3, t4| ---enable_warnings - -create table t3(a int primary key auto_increment)| -create table t4(a int primary key auto_increment)| - -create procedure bug14304() -begin - insert into t3 set a=null; - insert into t4 set a=null; - insert into t4 set a=null; - insert into t4 set a=null; - insert into t4 set a=null; - insert into t4 set a=null; - insert into t4 select null as a; - - insert into t3 set a=null; - insert into t3 set a=null; - - select * from t3; -end| - -call bug14304()| - -drop procedure bug14304| -drop table t3, t4| - -# -# BUG#14376: MySQL crash on scoped variable (re)initialization -# ---disable_warnings -drop procedure if exists bug14376| ---enable_warnings - -create procedure bug14376() -begin - declare x int default x; -end| - -# Not the error we want, but that's what we got for now... ---error ER_BAD_FIELD_ERROR -call bug14376()| -drop procedure bug14376| - -create procedure bug14376() -begin - declare x int default 42; - - begin - declare x int default x; - - select x; - end; -end| - -call bug14376()| - -drop procedure bug14376| - -create procedure bug14376(x int) -begin - declare x int default x; - - select x; -end| - -call bug14376(4711)| - -drop procedure bug14376| - -# -# Bug#5967 "Stored procedure declared variable used instead of column" -# The bug should be fixed later. -# Test precedence of names of parameters, variable declarations, -# variable declarations in nested compound statements, table columns, -# table columns in cursor declarations. -# According to the standard, table columns take precedence over -# variable declarations. In MySQL 5.0 it's vice versa. -# - ---disable_warnings -drop procedure if exists bug5967| -drop table if exists t3| ---enable_warnings -create table t3 (a varchar(255))| -insert into t3 (a) values ("a - table column")| -create procedure bug5967(a varchar(255)) -begin - declare i varchar(255); - declare c cursor for select a from t3; - select a; - select a from t3 into i; - select i as 'Parameter takes precedence over table column'; open c; - fetch c into i; - close c; - select i as 'Parameter takes precedence over table column in cursors'; - begin - declare a varchar(255) default 'a - local variable'; - declare c1 cursor for select a from t3; - select a as 'A local variable takes precedence over parameter'; - open c1; - fetch c1 into i; - close c1; - select i as 'A local variable takes precedence over parameter in cursors'; - begin - declare a varchar(255) default 'a - local variable in a nested compound statement'; - declare c2 cursor for select a from t3; - select a as 'A local variable in a nested compound statement takes precedence over a local variable in the outer statement'; - select a from t3 into i; - select i as 'A local variable in a nested compound statement takes precedence over table column'; - open c2; - fetch c2 into i; - close c2; - select i as 'A local variable in a nested compound statement takes precedence over table column in cursors'; - end; - end; -end| -call bug5967("a - stored procedure parameter")| -drop procedure bug5967| - -# -# Bug#13012 "SP: REPAIR/BACKUP/RESTORE TABLE crashes the server" -# ---disable_warnings -drop procedure if exists bug13012| ---enable_warnings -create procedure bug13012() -BEGIN - REPAIR TABLE t1; - BACKUP TABLE t1 to '../tmp'; - DROP TABLE t1; - RESTORE TABLE t1 FROM '../tmp'; -END| -call bug13012()| -drop procedure bug13012| -create view v1 as select * from t1| -create procedure bug13012() -BEGIN - REPAIR TABLE t1,t2,t3,v1; - OPTIMIZE TABLE t1,t2,t3,v1; - ANALYZE TABLE t1,t2,t3,v1; -END| -call bug13012()| -call bug13012()| -call bug13012()| -drop procedure bug13012| -drop view v1; -select * from t1| - -# -# A test case for Bug#15392 "Server crashes during prepared statement -# execute": make sure that stored procedure check for error conditions -# properly and do not continue execution if an error has been set. -# -# It's necessary to use several DBs because in the original code -# the successful return of mysql_change_db overrode the error from -# execution. -drop schema if exists mysqltest1| -drop schema if exists mysqltest2| -drop schema if exists mysqltest3| -create schema mysqltest1| -create schema mysqltest2| -create schema mysqltest3| -use mysqltest3| - -create procedure mysqltest1.p1 (out prequestid varchar(100)) -begin - call mysqltest2.p2('call mysqltest3.p3(1, 2)'); -end| - -create procedure mysqltest2.p2(in psql text) -begin - declare lsql text; - set @lsql= psql; - prepare lstatement from @lsql; - execute lstatement; - deallocate prepare lstatement; -end| - -create procedure mysqltest3.p3(in p1 int) -begin - select p1; -end| - ---error ER_SP_WRONG_NO_OF_ARGS -call mysqltest1.p1(@rs)| ---error ER_SP_WRONG_NO_OF_ARGS -call mysqltest1.p1(@rs)| ---error ER_SP_WRONG_NO_OF_ARGS -call mysqltest1.p1(@rs)| -drop schema if exists mysqltest1| -drop schema if exists mysqltest2| -drop schema if exists mysqltest3| -use test| - -# -# Bug#15441 "Running SP causes Server to Crash": check that an SP variable -# can not be used in VALUES() function. -# ---disable_warnings -drop table if exists t3| -drop procedure if exists bug15441| ---enable_warnings -create table t3 (id int not null primary key, county varchar(25))| -insert into t3 (id, county) values (1, 'York')| - -# First check that a stored procedure that refers to a parameter in VALUES() -# function won't parse. - -create procedure bug15441(c varchar(25)) -begin - update t3 set id=2, county=values(c); -end| ---error ER_BAD_FIELD_ERROR -call bug15441('county')| -drop procedure bug15441| - -# Now check the case when there is an ambiguity between column names -# and stored procedure parameters: the parser shall resolve the argument -# of VALUES() function to the column name. - -# It's hard to deduce what county refers to in every case (INSERT statement): -# 1st county refers to the column -# 2nd county refers to the procedure parameter -# 3d and 4th county refers to the column, again, but -# for 4th county it has the value of SP parameter - -# In UPDATE statement, just check that values() function returns NULL for -# non- INSERT...UPDATE statements, as stated in the manual. - -create procedure bug15441(county varchar(25)) -begin - declare c varchar(25) default "hello"; - - insert into t3 (id, county) values (1, county) - on duplicate key update county= values(county); - select * from t3; - - update t3 set id=2, county=values(id); - select * from t3; -end| -call bug15441('Yale')| -drop table t3| -drop procedure bug15441| - -# -# BUG#14498: Stored procedures: hang if undefined variable and exception -# ---disable_warnings -drop procedure if exists bug14498_1| -drop procedure if exists bug14498_2| -drop procedure if exists bug14498_3| -drop procedure if exists bug14498_4| -drop procedure if exists bug14498_5| ---enable_warnings - -create procedure bug14498_1() -begin - declare continue handler for sqlexception select 'error' as 'Handler'; - - if v then - select 'yes' as 'v'; - else - select 'no' as 'v'; - end if; - select 'done' as 'End'; -end| - -create procedure bug14498_2() -begin - declare continue handler for sqlexception select 'error' as 'Handler'; - - while v do - select 'yes' as 'v'; - end while; - select 'done' as 'End'; -end| - -create procedure bug14498_3() -begin - declare continue handler for sqlexception select 'error' as 'Handler'; - - repeat - select 'maybe' as 'v'; - until v end repeat; - select 'done' as 'End'; -end| - -create procedure bug14498_4() -begin - declare continue handler for sqlexception select 'error' as 'Handler'; - - case v - when 1 then - select '1' as 'v'; - when 2 then - select '2' as 'v'; - else - select '?' as 'v'; - end case; - select 'done' as 'End'; -end| - -create procedure bug14498_5() -begin - declare continue handler for sqlexception select 'error' as 'Handler'; - - case - when v = 1 then - select '1' as 'v'; - when v = 2 then - select '2' as 'v'; - else - select '?' as 'v'; - end case; - select 'done' as 'End'; -end| - -call bug14498_1()| -call bug14498_2()| -call bug14498_3()| -call bug14498_4()| -call bug14498_5()| - -drop procedure bug14498_1| -drop procedure bug14498_2| -drop procedure bug14498_3| -drop procedure bug14498_4| -drop procedure bug14498_5| - -# -# BUG#15231: Stored procedure bug with not found condition handler -# ---disable_warnings -drop table if exists t3| -drop procedure if exists bug15231_1| -drop procedure if exists bug15231_2| -drop procedure if exists bug15231_3| -drop procedure if exists bug15231_4| ---enable_warnings - -create table t3 (id int not null)| - -create procedure bug15231_1() -begin - declare xid integer; - declare xdone integer default 0; - declare continue handler for not found set xdone = 1; - - set xid=null; - call bug15231_2(xid); - select xid, xdone; -end| - -create procedure bug15231_2(inout ioid integer) -begin - select "Before NOT FOUND condition is triggered" as '1'; - select id into ioid from t3 where id=ioid; - select "After NOT FOUND condtition is triggered" as '2'; - - if ioid is null then - set ioid=1; - end if; -end| - -create procedure bug15231_3() -begin - declare exit handler for sqlwarning - select 'Caught it (wrong)' as 'Result'; - - call bug15231_4(); -end| - -create procedure bug15231_4() -begin - declare x decimal(2,1); - - set x = 'zap'; - select 'Missed it (correct)' as 'Result'; -end| - -call bug15231_1()| -call bug15231_3()| - -drop table if exists t3| -drop procedure if exists bug15231_1| -drop procedure if exists bug15231_2| -drop procedure if exists bug15231_3| -drop procedure if exists bug15231_4| - - -# -# BUG#15011: error handler in nested block not activated -# ---disable_warnings -drop procedure if exists bug15011| ---enable_warnings - -create table t3 (c1 int primary key)| - -insert into t3 values (1)| - -create procedure bug15011() - deterministic -begin - declare continue handler for 1062 - select 'Outer' as 'Handler'; - - begin - declare continue handler for 1062 - select 'Inner' as 'Handler'; - - insert into t3 values (1); - end; -end| - -call bug15011()| - -drop procedure bug15011| -drop table t3| - - -# -# BUG#NNNN: New bug synopsis -# -#--disable_warnings -#drop procedure if exists bugNNNN| -#--enable_warnings -#create procedure bugNNNN... - -# Add bugs above this line. Use existing tables t1 and t2 when -# practical, or create table t3, t4 etc temporarily (and drop them). -delimiter ;| -drop table t1,t2; diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index ce269b42ee9..6f22b81172d 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -13,7 +13,9 @@ DROP TABLE IF EXISTS t1; # Test INSERT with DATE CREATE TABLE t1 (col1 date); -INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29'); +INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29'); +--error 1292 +INSERT INTO t1 VALUES('0000-10-31'); # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> @@ -97,7 +99,9 @@ set @@sql_mode='ansi,traditional'; # Test INSERT with DATETIME CREATE TABLE t1 (col1 datetime); -INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00'); +INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00'); +--error 1292 +INSERT INTO t1 VALUES('0000-10-31 15:30:00'); # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> @@ -190,6 +194,7 @@ INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> +--error 1292 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); --error 1292 @@ -211,6 +216,7 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> +--error 1292 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); --error 1292 @@ -264,6 +270,8 @@ INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); ## Test INSERT with CAST AS DATE into DATE # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> + +--error 1292 INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE)); --error 1292 @@ -290,6 +298,8 @@ INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE)); ## Test INSERT with CAST AS DATETIME into DATETIME # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> + +--error 1292 INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); --error 1292 @@ -356,6 +366,8 @@ INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); ## Test INSERT with CONVERT to DATE into DATE # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> + +--error 1292 INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE)); --error 1292 @@ -381,6 +393,8 @@ INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE)); ## Test INSERT with CONVERT to DATETIME into DATETIME # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> + +--error 1292 INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); --error 1292 diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 8bf8337714f..ed122e9ff5a 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1851,6 +1851,47 @@ select 1 from dual where 2 > any (select 1); select 1 from dual where 2 > all (select 1); select 1 from dual where 1 < any (select 2 from dual); select 1 from dual where 1 < all (select 2 from dual where 1!=1); + +# BUG#20975 Wrong query results for subqueries within NOT +create table t1 (s1 char); +insert into t1 values (1),(2); + +select * from t1 where (s1 < any (select s1 from t1)); +select * from t1 where not (s1 < any (select s1 from t1)); + +select * from t1 where (s1 < ALL (select s1+1 from t1)); +select * from t1 where not(s1 < ALL (select s1+1 from t1)); + +select * from t1 where (s1+1 = ANY (select s1 from t1)); +select * from t1 where NOT(s1+1 = ANY (select s1 from t1)); + +select * from t1 where (s1 = ALL (select s1/s1 from t1)); +select * from t1 where NOT(s1 = ALL (select s1/s1 from t1)); +drop table t1; + +# +# Bug #16255: Subquery in where +# +create table t1 ( + retailerID varchar(8) NOT NULL, + statusID int(10) unsigned NOT NULL, + changed datetime NOT NULL, + UNIQUE KEY retailerID (retailerID, statusID, changed) +); + +INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56"); +INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53"); +INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56"); +INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53"); +INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50"); +INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50"); + +select * from t1 r1 + where (r1.retailerID,(r1.changed)) in + (SELECT r2.retailerId,(max(changed)) from t1 r2 + group by r2.retailerId); +drop table t1; + # End of 4.1 tests # diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test index b21eda176b6..162bdd0d90a 100644 --- a/mysql-test/t/subselect2.test +++ b/mysql-test/t/subselect2.test @@ -150,3 +150,21 @@ EXPLAIN SELECT t2.*, t4.DOCTYPENAME, t1.CONTENTSIZE,t1.MIMETYPE FROM t2 INNER JO drop table t1, t2, t3, t4; # End of 4.1 tests + +# +# Bug #20792: Incorrect results from aggregate subquery +# +CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB; +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (a int(10), PRIMARY KEY (a)) Engine=InnoDB; +INSERT INTO t2 VALUES (1); + +CREATE TABLE t3 (a int(10), b int(10), c int(10), + PRIMARY KEY (a)) Engine=InnoDB; +INSERT INTO t3 VALUES (1,2,1); + +SELECT t1.* FROM t1 WHERE (SELECT COUNT(*) FROM t3,t2 WHERE t3.c=t2.a + and t2.a='1' AND t1.a=t3.b) > 0; + +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test index 0a2ab180806..fa44b454b4f 100644 --- a/mysql-test/t/system_mysql_db_fix.test +++ b/mysql-test/t/system_mysql_db_fix.test @@ -1,6 +1,9 @@ # Embedded server doesn't support external clients --source include/not_embedded.inc +# Windows doesn't support execution of shell scripts (to fix!!) +--source include/not_windows.inc + # # This is the test for mysql_fix_privilege_tables # diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index 95e8eaae83e..2a145e1eeaa 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -651,17 +651,105 @@ drop table t1; # of functions and triggers. create table t1 (id int); --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row reset query cache; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row reset master; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row reset slave; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush hosts; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush tables with read lock; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush logs; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush status; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush slave; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush master; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush des_key_file; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +create trigger t1_ai after insert on t1 for each row flush user_resources; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create trigger t1_ai after insert on t1 for each row flush tables; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create trigger t1_ai after insert on t1 for each row flush privileges; -create procedure p1() flush tables; +--disable_warnings +drop procedure if exists p1; +--enable_warnings + create trigger t1_ai after insert on t1 for each row call p1(); +create procedure p1() flush tables; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() reset query cache; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG insert into t1 values (0); + +drop procedure p1; +create procedure p1() reset master; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() reset slave; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush hosts; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + drop procedure p1; create procedure p1() flush privileges; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush tables with read lock; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush tables; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush logs; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush status; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush slave; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush master; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush des_key_file; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + +drop procedure p1; +create procedure p1() flush user_resources; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +insert into t1 values (0); + drop procedure p1; drop table t1; @@ -1301,6 +1389,36 @@ create trigger wont_work after update on event for each row begin set @a:= 1; end| +use test| delimiter ;| + +# +# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause. +# + +# Prepare. + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); + +--error ER_WRONG_STRING_LENGTH +CREATE DEFINER=1234567890abcdefGHIKL@localhost + TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1; + +--error ER_WRONG_STRING_LENGTH +CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY + TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2; + +# Cleanup. + +DROP TABLE t1; +DROP TABLE t2; + + --echo End of 5.0 tests diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index e028dbc51d9..998f8f18fbe 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -238,4 +238,19 @@ select * from t1; --disable_metadata drop table t1; +# +# Bug#15583: BIN()/OCT()/CONV() do not work with BIT values +# +create table bug15583(b BIT(8), n INT); +insert into bug15583 values(128, 128); +insert into bug15583 values(null, null); +insert into bug15583 values(0, 0); +insert into bug15583 values(255, 255); +select hex(b), bin(b), oct(b), hex(n), bin(n), oct(n) from bug15583; +select hex(b)=hex(n) as should_be_onetrue, bin(b)=bin(n) as should_be_onetrue, oct(b)=oct(n) as should_be_onetrue from bug15583; +select hex(b + 0), bin(b + 0), oct(b + 0), hex(n), bin(n), oct(n) from bug15583; +select conv(b, 10, 2), conv(b + 0, 10, 2) from bug15583; +drop table bug15583; + + --echo End of 5.0 tests diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 503d7ffc0b9..6d79dcc863b 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -423,3 +423,18 @@ alter table t1 modify a binary(5); select hex(a) from t1 order by a; select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0'); drop table t1; + +# +# Bug #19489: Inconsistent support for DEFAULT in TEXT columns +# +create table t1 (a text default ''); +show create table t1; +insert into t1 values (default); +select * from t1; +drop table t1; +set @@sql_mode='TRADITIONAL'; +--error ER_BLOB_CANT_HAVE_DEFAULT +create table t1 (a text default ''); +set @@sql_mode=''; + +--echo End of 5.0 tests diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index 4b6741b4242..cdf73bf6c89 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -114,3 +114,14 @@ select * from t1; drop table t1; # End of 4.1 tests + +# +# Bug#21475: Wrongly applied constant propagation leads to a false comparison. +# +CREATE TABLE t1(a DATETIME NOT NULL); +INSERT INTO t1 VALUES ('20060606155555'); +SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555"); +PREPARE s FROM 'SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555")'; +EXECUTE s; +DROP PREPARE s; +DROP TABLE t1; diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 35aff8b3c5a..de1ebd74d17 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -947,8 +947,12 @@ select cast('1.00000001335143196001808973960578441619873046875E-10' as decimal(3 # # Bug #11708 (conversion to decimal fails in decimal part) # -select ln(14000) c1, convert(ln(14000),decimal(2,3)) c2, cast(ln(14000) as decimal(2,3)) c3; - +select ln(14000) c1, convert(ln(14000),decimal(5,3)) c2, cast(ln(14000) as decimal(5,3)) c3; +--error 1427 +select convert(ln(14000),decimal(2,3)) c1; +--error 1427 +select cast(ln(14000) as decimal(2,3)) c1; + # # Bug #8449 (Silent column changes) # diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index ddfc3f11665..7b4af9e0c69 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -328,3 +328,14 @@ drop table t1; # Restore timezone to default set time_zone= @@global.time_zone; + +CREATE TABLE t1 ( +`id` int(11) NOT NULL auto_increment, +`username` varchar(80) NOT NULL default '', +`posted_on` timestamp NOT NULL default '0000-00-00 00:00:00', +PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1; + +show fields from t1; +select is_nullable from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='t1' and COLUMN_NAME='posted_on'; +drop table t1; diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test index e5614afe4f6..439e98471b2 100644 --- a/mysql-test/t/type_varchar.test +++ b/mysql-test/t/type_varchar.test @@ -146,3 +146,44 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test'); INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3)); DROP TABLE IF EXISTS t1; + +# +# Bug#14897 "ResultSet.getString("table.column") sometimes doesn't find the +# column" +# Test that after upgrading an old 4.1 VARCHAR column to 5.0 VARCHAR we preserve +# the original column metadata. +# +--disable_warnings +drop table if exists t1, t2, t3; +--enable_warnings + +create table t3 ( + id int(11), + en varchar(255) character set utf8, + cz varchar(255) character set utf8 +); +system cp $MYSQL_TEST_DIR/std_data/14897.frm $MYSQLTEST_VARDIR/master-data/test/t3.frm; +truncate table t3; +insert into t3 (id, en, cz) values +(1,'en string 1','cz string 1'), +(2,'en string 2','cz string 2'), +(3,'en string 3','cz string 3'); + +create table t1 ( + id int(11), + name_id int(11) +); +insert into t1 (id, name_id) values (1,1), (2,3), (3,3); + +create table t2 (id int(11)); +insert into t2 (id) values (1), (2), (3); + +# max_length is different for varchar fields in ps-protocol and we can't +# replace a single metadata column, disable PS protocol +--disable_ps_protocol +--enable_metadata +select t1.*, t2.id, t3.en, t3.cz from t1 left join t2 on t1.id=t2.id +left join t3 on t1.id=t3.id order by t3.id; +--disable_metadata +--enable_ps_protocol +drop table t1, t2, t3; diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index e0c2493c616..96e559f5c05 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -109,6 +109,24 @@ SELECT myfunc_double(n) AS f FROM bug19904; SELECT metaphon(v) AS f FROM bug19904; DROP TABLE bug19904; +# +# Bug#21269: DEFINER-clause is allowed for UDF-functions +# + +--error ER_WRONG_USAGE +CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; + +--error ER_WRONG_USAGE +CREATE DEFINER=someone@somewhere FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; +# +# Bug#19862: Sort with filesort by function evaluates function twice +# +create table t1(f1 int); +insert into t1 values(1),(2); +explain select myfunc_int(f1) from t1 order by 1; +drop table t1; --echo End of 5.0 tests. # diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 7dfe4ac482f..bf5c5e066f0 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -390,8 +390,8 @@ create table t1 SELECT da from t2 UNION select dt from t2; select * from t1; show create table t1; drop table t1; -create table t1 SELECT dt from t2 UNION select sc from t2; -select * from t1; +create table t1 SELECT dt from t2 UNION select trim(sc) from t2; +select trim(dt) from t1; show create table t1; drop table t1; create table t1 SELECT dt from t2 UNION select sv from t2; @@ -795,6 +795,14 @@ drop table t1; # End of 4.1 tests # +# Bug#12185: Data type aggregation may produce wrong result +# +create table t1(f1 char(1), f2 char(5), f3 binary(1), f4 binary(5), f5 timestamp, f6 varchar(1) character set utf8 collate utf8_general_ci, f7 text); +create table t2 as select *, f6 as f8 from t1 union select *, f7 from t1; +show create table t2; +drop table t1, t2; + +# # Bug#18175: Union select over 129 tables with a sum function fails. # (select avg(1)) union (select avg(1)) union (select avg(1)) union @@ -841,3 +849,10 @@ drop table t1; (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)); +# +# Bug #16881: password() and union select +# (The issue was poor handling of character set aggregation.) +# +select _utf8'12' union select _latin1'12345'; + +--echo End of 5.0 tests diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index e1b23a1782f..644ca506eba 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -144,9 +144,6 @@ select @@version; --replace_column 1 # select @@global.version; -# End of 4.1 tests - -# # Bug #6598: problem with cast(NULL as signed integer); # @@ -171,3 +168,46 @@ set @first_var= cast(NULL as CHAR); create table t1 select @first_var; show create table t1; drop table t1; + +# +# Bug #7498 User variable SET saves SIGNED BIGINT as UNSIGNED BIGINT +# + +# First part, set user var to large number and select it +set @a=18446744071710965857; +select @a; + +# Second part, set user var from large number in table +# then select it +CREATE TABLE `bigfailure` ( + `afield` BIGINT UNSIGNED NOT NULL +); +INSERT INTO `bigfailure` VALUES (18446744071710965857); +SELECT * FROM bigfailure; +select * from (SELECT afield FROM bigfailure) as b; +select * from bigfailure where afield = (SELECT afield FROM bigfailure); +select * from bigfailure where afield = 18446744071710965857; +# This is fixed in 5.0, to be uncommented there +#select * from bigfailure where afield = '18446744071710965857'; +select * from bigfailure where afield = 18446744071710965856+1; + +SET @a := (SELECT afield FROM bigfailure); +SELECT @a; +SET @a := (select afield from (SELECT afield FROM bigfailure) as b); +SELECT @a; +SET @a := (select * from bigfailure where afield = (SELECT afield FROM bigfailure)); +SELECT @a; + +drop table bigfailure; + +# +# Bug#16861: User defined variable can have a wrong value if a tmp table was +# used. +# +create table t1(f1 int, f2 int); +insert into t1 values (1,2),(2,3),(3,1); +select @var:=f2 from t1 group by f1 order by f2 desc limit 1; +select @var; +drop table t1; + +# End of 4.1 tests diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 88a4d489039..edff38274c4 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2643,3 +2643,195 @@ DESCRIBE t2; DROP VIEW v1; DROP TABLE t1,t2; + +# +# Bug #17526: views with TRIM functions +# + +CREATE TABLE t1 (s varchar(10)); +INSERT INTO t1 VALUES ('yadda'), ('yady'); + +SELECT TRIM(BOTH 'y' FROM s) FROM t1; +CREATE VIEW v1 AS SELECT TRIM(BOTH 'y' FROM s) FROM t1; +SELECT * FROM v1; +DROP VIEW v1; + +SELECT TRIM(LEADING 'y' FROM s) FROM t1; +CREATE VIEW v1 AS SELECT TRIM(LEADING 'y' FROM s) FROM t1; +SELECT * FROM v1; +DROP VIEW v1; + +SELECT TRIM(TRAILING 'y' FROM s) FROM t1; +CREATE VIEW v1 AS SELECT TRIM(TRAILING 'y' FROM s) FROM t1; +SELECT * FROM v1; +DROP VIEW v1; + +DROP TABLE t1; + +# +#Bug #21080: ALTER VIEW makes user restate SQL SECURITY mode, and ALGORITHM +# +CREATE TABLE t1 (x INT, y INT); +CREATE ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +SHOW CREATE VIEW v1; + +ALTER VIEW v1 AS SELECT x, y FROM t1; +SHOW CREATE VIEW v1; + +DROP VIEW v1; +DROP TABLE t1; +# Bug #21086: server crashes when VIEW defined with a SELECT with COLLATE +# clause is called +# +CREATE TABLE t1 (s1 char); +INSERT INTO t1 VALUES ('Z'); + +CREATE VIEW v1 AS SELECT s1 collate latin1_german1_ci AS col FROM t1; + +CREATE VIEW v2 (col) AS SELECT s1 collate latin1_german1_ci FROM t1; + +# either of these statements will cause crash +INSERT INTO v1 (col) VALUES ('b'); +INSERT INTO v2 (col) VALUES ('c'); + +SELECT s1 FROM t1; +DROP VIEW v1, v2; +DROP TABLE t1; + +# +# Bug #11551: Asymmetric + undocumented behaviour of DROP VIEW and DROP TABLE +# +CREATE TABLE t1 (id INT); +CREATE VIEW v1 AS SELECT id FROM t1; +SHOW TABLES; + +--error 1051 +DROP VIEW v2,v1; +SHOW TABLES; + +CREATE VIEW v1 AS SELECT id FROM t1; +--error 1347 +DROP VIEW t1,v1; +SHOW TABLES; + +DROP TABLE t1; +--disable_warnings +DROP VIEW IF EXISTS v1; +--enable_warnings + +# +# Bug #21261: Wrong access rights was required for an insert to a view +# +CREATE DATABASE bug21261DB; +USE bug21261DB; +CONNECT (root,localhost,root,,bug21261DB); +CONNECTION root; + +CREATE TABLE t1 (x INT); +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1; +GRANT INSERT, UPDATE ON v1 TO 'user21261'@'localhost'; +GRANT INSERT, UPDATE ON t1 TO 'user21261'@'localhost'; +CREATE TABLE t2 (y INT); +GRANT SELECT ON t2 TO 'user21261'@'localhost'; + +CONNECT (user21261, localhost, user21261,, bug21261DB); +CONNECTION user21261; +INSERT INTO v1 (x) VALUES (5); +UPDATE v1 SET x=1; +CONNECTION root; +GRANT SELECT ON v1 TO 'user21261'@'localhost'; +GRANT SELECT ON t1 TO 'user21261'@'localhost'; +CONNECTION user21261; +UPDATE v1,t2 SET x=1 WHERE x=y; +CONNECTION root; +SELECT * FROM t1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user21261'@'localhost'; +DROP USER 'user21261'@'localhost'; +DROP VIEW v1; +DROP TABLE t1; +DROP DATABASE bug21261DB; +USE test; + +# +# Bug #15950: NOW() optimized away in VIEWs +# +create table t1 (f1 datetime); +create view v1 as select * from t1 where f1 between now() and now() + interval 1 minute; +show create view v1; +drop view v1; +drop table t1; +# +# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause. +# + +# Prepare. + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP VIEW IF EXISTS v2; +--enable_warnings + +CREATE TABLE t1(a INT, b INT); + +--error ER_WRONG_STRING_LENGTH +CREATE DEFINER=1234567890abcdefGHIKL@localhost + VIEW v1 AS SELECT a FROM t1; + +--error ER_WRONG_STRING_LENGTH +CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY + VIEW v2 AS SELECT b FROM t1; + +# Cleanup. + +DROP TABLE t1; + + +# +# BUG#17591: Updatable view not possible with trigger or stored +# function +# +# During prelocking phase we didn't update lock type of view tables, +# hence READ lock was always requested. +# +--disable_warnings +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP VIEW IF EXISTS v1, v2; +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (i INT); + +CREATE VIEW v1 AS SELECT * FROM t1; + +delimiter |; +CREATE FUNCTION f1() RETURNS INT +BEGIN + INSERT INTO v1 VALUES (0); + RETURN 0; +END | +delimiter ;| + +SELECT f1(); + +CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t1; + +delimiter |; +CREATE FUNCTION f2() RETURNS INT +BEGIN + INSERT INTO v2 VALUES (0); + RETURN 0; +END | +delimiter ;| + +--error ER_NON_UPDATABLE_TABLE +SELECT f2(); + +DROP FUNCTION f1; +DROP FUNCTION f2; +DROP VIEW v1, v2; +DROP TABLE t1; + + +--echo End of 5.0 tests. diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt new file mode 100755 index 00000000000..7926cb916c1 --- /dev/null +++ b/mysys/CMakeLists.txt @@ -0,0 +1,29 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +# Need to set USE_TLS, since mysys is linked into libmysql.dll and +# libmysqld.dll, and __declspec(thread) approach to thread local storage does +# not work properly in DLLs. +# Currently, USE_TLS crashes in Debug builds, so until that is fixed Debug +# .dlls cannot be loaded at runtime. +SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DUSE_TLS") +SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DUSE_TLS") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys ) +ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_modify.c + errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c + mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c + mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c + mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_tempdir.c + mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c + my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chsize.c + my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c + my_div.c my_error.c my_file.c my_fopen.c my_fstream.c my_gethostbyname.c + my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_handler.c my_init.c + my_lib.c my_lock.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c + my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c + my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c + my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c + my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c + rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c + thr_rwlock.c tree.c typelib.c base64.c my_memmem.c) diff --git a/mysys/Makefile.am b/mysys/Makefile.am index bc84f44cd29..041130fdf5c 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -58,7 +58,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ my_memmem.c \ my_windac.c my_access.c base64.c my_libwrap.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ - thr_mutex.c thr_rwlock.c + thr_mutex.c thr_rwlock.c mf_soundex.c my_conio.c \ + my_wincond.c my_winsem.c my_winthread.c CMakeLists.txt libmysys_a_LIBADD = @THREAD_LOBJECTS@ # test_dir_DEPENDENCIES= $(LIBRARIES) # testhash_DEPENDENCIES= $(LIBRARIES) diff --git a/mysys/my_open.c b/mysys/my_open.c index 6ed3cb5becf..a0168b23b16 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -335,7 +335,7 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) * try to open/create the file */ if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes, - filecreate, fileattrib, NULL)) == (HANDLE)0xffffffff) + filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE) { /* * OS call to open/create file failed! map the error, release @@ -346,7 +346,7 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) return -1; /* return error to caller */ } - fh= _open_osfhandle((long)osfh, oflag & (_O_APPEND | _O_RDONLY | _O_TEXT)); + fh= _open_osfhandle((intptr_t)osfh, oflag & (_O_APPEND | _O_RDONLY | _O_TEXT)); return fh; /* return handle */ } diff --git a/mysys/my_read.c b/mysys/my_read.c index 9de070e772d..2e23f2175f8 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -36,48 +36,51 @@ uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags) { - uint readbytes,save_count; + uint readbytes, save_count; DBUG_ENTER("my_read"); DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %u MyFlags: %d", - Filedes, Buffer, Count, MyFlags)); - save_count=Count; + Filedes, Buffer, Count, MyFlags)); + save_count= Count; for (;;) { - errno=0; /* Linux doesn't reset this */ - if ((readbytes = (uint) read(Filedes, Buffer, Count)) != Count) + errno= 0; /* Linux doesn't reset this */ + if ((readbytes= (uint) read(Filedes, Buffer, Count)) != Count) { - my_errno=errno ? errno : -1; + my_errno= errno ? errno : -1; DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d", - readbytes,Count,Filedes,my_errno)); + readbytes, Count, Filedes, my_errno)); #ifdef THREAD - if (readbytes == 0 && errno == EINTR) - continue; /* Interrupted */ + if ((int) readbytes <= 0 && errno == EINTR) + { + DBUG_PRINT("debug", ("my_read() was interrupted and returned %d", (int) readbytes)); + continue; /* Interrupted */ + } #endif if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { - if ((int) readbytes == -1) - my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),my_errno); - else if (MyFlags & (MY_NABP | MY_FNABP)) - my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),my_errno); + if ((int) readbytes == -1) + my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), + my_filename(Filedes),my_errno); + else if (MyFlags & (MY_NABP | MY_FNABP)) + my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), + my_filename(Filedes),my_errno); } if ((int) readbytes == -1 || - ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO))) - DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ + ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO))) + DBUG_RETURN(MY_FILE_ERROR); /* Return with error */ if (readbytes > 0 && (MyFlags & MY_FULL_IO)) { - Buffer+=readbytes; - Count-=readbytes; - continue; + Buffer+= readbytes; + Count-= readbytes; + continue; } } if (MyFlags & (MY_NABP | MY_FNABP)) - readbytes=0; /* Ok on read */ + readbytes= 0; /* Ok on read */ else if (MyFlags & MY_FULL_IO) - readbytes=save_count; + readbytes= save_count; break; } DBUG_RETURN(readbytes); diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 6af65d70fd0..8035312496d 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -29,7 +29,8 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, whence, MyFlags)); DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ - newpos=lseek(fd, pos, whence); + if (-1 != fd) + newpos=lseek(fd, pos, whence); if (newpos == (os_off_t) -1) { my_errno=errno; diff --git a/ndb/include/kernel/signaldata/CreateIndx.hpp b/ndb/include/kernel/signaldata/CreateIndx.hpp index a9dc653f349..4163583dbd2 100644 --- a/ndb/include/kernel/signaldata/CreateIndx.hpp +++ b/ndb/include/kernel/signaldata/CreateIndx.hpp @@ -192,6 +192,7 @@ public: enum ErrorCode { NoError = 0, Busy = 701, + BusyWithNR = 711, NotMaster = 702, TriggerNotFound = 4238, TriggerExists = 4239, diff --git a/ndb/include/kernel/signaldata/DropIndx.hpp b/ndb/include/kernel/signaldata/DropIndx.hpp index fd2ea7f0b7b..41ee50082f7 100644 --- a/ndb/include/kernel/signaldata/DropIndx.hpp +++ b/ndb/include/kernel/signaldata/DropIndx.hpp @@ -168,6 +168,7 @@ public: NoError = 0, InvalidIndexVersion = 241, Busy = 701, + BusyWithNR = 711, NotMaster = 702, IndexNotFound = 4243, BadRequestType = 4247, diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 4db541f7fe4..dbc343d2238 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -477,7 +477,7 @@ public: /** * Interpreted program instruction: - * Substract RegSource1 from RegSource2 and put the result in RegDest. + * Substract RegSource2 from RegSource1 and put the result in RegDest. * * @param RegSource1 First register. * @param RegSource2 Second register. diff --git a/ndb/include/ndbapi/NdbTransaction.hpp b/ndb/include/ndbapi/NdbTransaction.hpp index a6ba6a11c4d..6a80d6bf22c 100644 --- a/ndb/include/ndbapi/NdbTransaction.hpp +++ b/ndb/include/ndbapi/NdbTransaction.hpp @@ -140,6 +140,7 @@ class NdbTransaction friend class NdbIndexOperation; friend class NdbIndexScanOperation; friend class NdbBlob; + friend class ha_ndbcluster; #endif public: @@ -791,6 +792,7 @@ private: // optim: any blobs bool theBlobFlag; Uint8 thePendingBlobOps; + inline bool hasBlobOperation() { return theBlobFlag; } static void sendTC_COMMIT_ACK(NdbApiSignal *, Uint32 transId1, Uint32 transId2, diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 7fee2e92f2b..c8c9e82efc2 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -6,7 +6,7 @@ Next DBTUP 4014 Next DBLQH 5043 Next DBDICT 6007 Next DBDIH 7177 -Next DBTC 8037 +Next DBTC 8038 Next CMVMI 9000 Next BACKUP 10022 Next DBUTIL 11002 @@ -283,6 +283,7 @@ ABORT OF TCKEYREQ 8032: No free TC records any more +8037 : Invalid schema version in TCINDXREQ CMVMI ----- diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp index 43c1de5e2b3..10318e5f52d 100644 --- a/ndb/src/kernel/blocks/backup/Backup.cpp +++ b/ndb/src/kernel/blocks/backup/Backup.cpp @@ -274,36 +274,48 @@ Backup::execCONTINUEB(Signal* signal) BackupRecordPtr ptr; c_backupPool.getPtr(ptr, ptr_I); - TablePtr tabPtr; - ptr.p->tables.getPtr(tabPtr, tabPtr_I); - FragmentPtr fragPtr; - tabPtr.p->fragments.getPtr(fragPtr, fragPtr_I); - BackupFilePtr filePtr; - ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr); - - const Uint32 sz = sizeof(BackupFormat::CtlFile::FragmentInfo) >> 2; - Uint32 * dst; - if (!filePtr.p->operation.dataBuffer.getWritePtr(&dst, sz)) + if (tabPtr_I == RNIL) { - sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 4); + closeFiles(signal, ptr); return; } + jam(); + TablePtr tabPtr; + ptr.p->tables.getPtr(tabPtr, tabPtr_I); + jam(); + if(tabPtr.p->fragments.getSize()) + { + FragmentPtr fragPtr; + tabPtr.p->fragments.getPtr(fragPtr, fragPtr_I); - BackupFormat::CtlFile::FragmentInfo * fragInfo = - (BackupFormat::CtlFile::FragmentInfo*)dst; - fragInfo->SectionType = htonl(BackupFormat::FRAGMENT_INFO); - fragInfo->SectionLength = htonl(sz); - fragInfo->TableId = htonl(fragPtr.p->tableId); - fragInfo->FragmentNo = htonl(fragPtr_I); - fragInfo->NoOfRecordsLow = htonl(fragPtr.p->noOfRecords & 0xFFFFFFFF); - fragInfo->NoOfRecordsHigh = htonl(fragPtr.p->noOfRecords >> 32); - fragInfo->FilePosLow = htonl(0 & 0xFFFFFFFF); - fragInfo->FilePosHigh = htonl(0 >> 32); + BackupFilePtr filePtr; + ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr); - filePtr.p->operation.dataBuffer.updateWritePtr(sz); + const Uint32 sz = sizeof(BackupFormat::CtlFile::FragmentInfo) >> 2; + Uint32 * dst; + if (!filePtr.p->operation.dataBuffer.getWritePtr(&dst, sz)) + { + sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 4); + return; + } + + BackupFormat::CtlFile::FragmentInfo * fragInfo = + (BackupFormat::CtlFile::FragmentInfo*)dst; + fragInfo->SectionType = htonl(BackupFormat::FRAGMENT_INFO); + fragInfo->SectionLength = htonl(sz); + fragInfo->TableId = htonl(fragPtr.p->tableId); + fragInfo->FragmentNo = htonl(fragPtr_I); + fragInfo->NoOfRecordsLow = htonl(fragPtr.p->noOfRecords & 0xFFFFFFFF); + fragInfo->NoOfRecordsHigh = htonl(fragPtr.p->noOfRecords >> 32); + fragInfo->FilePosLow = htonl(0 & 0xFFFFFFFF); + fragInfo->FilePosHigh = htonl(0 >> 32); + + filePtr.p->operation.dataBuffer.updateWritePtr(sz); + + fragPtr_I++; + } - fragPtr_I++; if (fragPtr_I == tabPtr.p->fragments.getSize()) { signal->theData[0] = tabPtr.p->tableId; @@ -4243,6 +4255,12 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal) TablePtr tabPtr; ptr.p->tables.first(tabPtr); + if (tabPtr.i == RNIL) + { + closeFiles(signal, ptr); + return; + } + signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO; signal->theData[1] = ptr.i; signal->theData[2] = tabPtr.i; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index efd519339f7..a79ddd05fae 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -6520,9 +6520,18 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) } if (signal->getLength() == CreateIndxReq::SignalLength) { jam(); + CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError; if (getOwnNodeId() != c_masterNodeId) { jam(); - + tmperr = CreateIndxRef::NotMaster; + } else if (c_blockState == BS_NODE_RESTART) { + jam(); + tmperr = CreateIndxRef::BusyWithNR; + } else if (c_blockState != BS_IDLE) { + jam(); + tmperr = CreateIndxRef::Busy; + } + if (tmperr != CreateIndxRef::NoError) { releaseSections(signal); OpCreateIndex opBusy; opPtr.p = &opBusy; @@ -6530,13 +6539,12 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal) opPtr.p->m_isMaster = (senderRef == reference()); opPtr.p->key = 0; opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE; - opPtr.p->m_errorCode = CreateIndxRef::NotMaster; + opPtr.p->m_errorCode = tmperr; opPtr.p->m_errorLine = __LINE__; opPtr.p->m_errorNode = c_masterNodeId; createIndex_sendReply(signal, opPtr, true); return; } - // forward initial request plus operation key to all req->setOpKey(++c_opRecordSequence); NodeReceiverGroup rg(DBDICT, c_aliveNodes); @@ -7082,10 +7090,19 @@ Dbdict::execDROP_INDX_REQ(Signal* signal) jam(); if (signal->getLength() == DropIndxReq::SignalLength) { jam(); + DropIndxRef::ErrorCode tmperr = DropIndxRef::NoError; if (getOwnNodeId() != c_masterNodeId) { jam(); - - err = DropIndxRef::NotMaster; + tmperr = DropIndxRef::NotMaster; + } else if (c_blockState == BS_NODE_RESTART) { + jam(); + tmperr = DropIndxRef::BusyWithNR; + } else if (c_blockState != BS_IDLE) { + jam(); + tmperr = DropIndxRef::Busy; + } + if (tmperr != DropIndxRef::NoError) { + err = tmperr; goto error; } // forward initial request plus operation key to all @@ -10130,6 +10147,17 @@ Dbdict::execDICT_LOCK_REQ(Signal* signal) sendDictLockInfoEvent(lockPtr, "lock request by node"); } +// only table and index ops are checked +bool +Dbdict::hasDictLockSchemaOp() +{ + return + ! c_opCreateTable.isEmpty() || + ! c_opDropTable.isEmpty() || + ! c_opCreateIndex.isEmpty() || + ! c_opDropIndex.isEmpty(); +} + void Dbdict::checkDictLockQueue(Signal* signal, bool poll) { @@ -10150,7 +10178,7 @@ Dbdict::checkDictLockQueue(Signal* signal, bool poll) break; } - if (c_opRecordPool.getNoOfFree() != c_opRecordPool.getSize()) { + if (hasDictLockSchemaOp()) { jam(); break; } @@ -10183,7 +10211,7 @@ Dbdict::execDICT_UNLOCK_ORD(Signal* signal) if (lockPtr.p->locked) { jam(); ndbrequire(c_blockState == lockPtr.p->lt->blockState); - ndbrequire(c_opRecordPool.getNoOfFree() == c_opRecordPool.getSize()); + ndbrequire(! hasDictLockSchemaOp()); ndbrequire(! c_dictLockQueue.hasPrev(lockPtr)); c_blockState = BS_IDLE; @@ -10279,7 +10307,7 @@ Dbdict::removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes) if (lockPtr.p->locked) { jam(); ndbrequire(c_blockState == lockPtr.p->lt->blockState); - ndbrequire(c_opRecordPool.getNoOfFree() == c_opRecordPool.getSize()); + ndbrequire(! hasDictLockSchemaOp()); ndbrequire(! c_dictLockQueue.hasPrev(lockPtr)); c_blockState = BS_IDLE; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index ed8b7e3b822..82644826d5b 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -1650,6 +1650,9 @@ private: void sendDictLockInfoEvent(Uint32 pollCount); void sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text); + // check if any schema op exists (conflicting with dict lock) + bool hasDictLockSchemaOp(); + void checkDictLockQueue(Signal* signal, bool poll); void sendDictLockConf(Signal* signal, DictLockPtr lockPtr); void sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode); diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 491aa0849b9..1c1fdb41d51 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -8252,11 +8252,21 @@ void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr) /* WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE */ /* DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */ /* ---------------------------------------------------------------------- */ - ndbrequire(filePtr.i == tabPtr.p->tabFile[0]); - filePtr.i = tabPtr.p->tabFile[1]; - ptrCheckGuard(filePtr, cfileFileSize, fileRecord); - openFileRw(signal, filePtr); - filePtr.p->reqStatus = FileRecord::OPENING_TABLE; + if (filePtr.i == tabPtr.p->tabFile[0]) + { + filePtr.i = tabPtr.p->tabFile[1]; + ptrCheckGuard(filePtr, cfileFileSize, fileRecord); + openFileRw(signal, filePtr); + filePtr.p->reqStatus = FileRecord::OPENING_TABLE; + } + else + { + char buf[256]; + BaseString::snprintf(buf, sizeof(buf), + "Error opening DIH schema files for table: %d", + tabPtr.i); + progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf); + } }//Dbdih::openingTableErrorLab() void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr) @@ -8422,6 +8432,7 @@ Dbdih::resetReplicaSr(TabRecordPtr tabPtr){ } replicaPtr.i = nextReplicaPtrI; }//while + updateNodeInfo(fragPtr); } } diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 0ea49e47fc7..7286481002f 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -6470,6 +6470,7 @@ void Dblqh::execACC_ABORTCONF(Signal* signal) * A NORMAL EVENT DURING CREATION OF A FRAGMENT. WE NOW NEED TO CONTINUE * WITH NORMAL COMMIT PROCESSING. * ---------------------------------------------------------------------- */ + regTcPtr->totSendlenAi = regTcPtr->totReclenAi; if (regTcPtr->currTupAiLen == regTcPtr->totReclenAi) { jam(); regTcPtr->abortState = TcConnectionrec::ABORT_IDLE; @@ -12579,19 +12580,17 @@ void Dblqh::lastWriteInFileLab(Signal* signal) void Dblqh::writePageZeroLab(Signal* signal) { - if (false && logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM) + if (logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM) { if (logPartPtr.p->firstLogQueue == RNIL) { jam(); logPartPtr.p->logPartState = LogPartRecord::IDLE; - ndbout_c("resetting logPartState to IDLE"); } else { jam(); logPartPtr.p->logPartState = LogPartRecord::ACTIVE; - ndbout_c("resetting logPartState to ACTIVE"); } } @@ -14623,6 +14622,8 @@ void Dblqh::execSr(Signal* signal) LogFileRecordPtr nextLogFilePtr; LogPageRecordPtr tmpLogPagePtr; Uint32 logWord; + Uint32 line; + const char * crash_msg = 0; jamEntry(); logPartPtr.i = signal->theData[0]; @@ -14833,8 +14834,14 @@ void Dblqh::execSr(Signal* signal) /* PLACE THAN IN THE FIRST PAGE OF A NEW FILE IN THE FIRST POSITION AFTER THE*/ /* HEADER. */ /*---------------------------------------------------------------------------*/ - ndbrequire(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] == - (ZPAGE_HEADER_SIZE + ZPOS_NO_FD)); + if (unlikely(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] != + (ZPAGE_HEADER_SIZE + ZPOS_NO_FD))) + { + line = __LINE__; + logWord = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]; + crash_msg = "ZFD_TYPE at incorrect position!"; + goto crash; + } { Uint32 noFdDescriptors = logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD]; @@ -14871,19 +14878,10 @@ void Dblqh::execSr(Signal* signal) /*---------------------------------------------------------------------------*/ /* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */ /*---------------------------------------------------------------------------*/ - signal->theData[0] = RNIL; - signal->theData[1] = logPartPtr.i; - Uint32 tmp = logFilePtr.p->fileName[3]; - tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX. - signal->theData[2] = tmp; - signal->theData[3] = logFilePtr.p->fileNo; - signal->theData[4] = logFilePtr.p->currentFilepage; - signal->theData[5] = logFilePtr.p->currentMbyte; - signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]; - signal->theData[7] = ~0; - signal->theData[8] = __LINE__; - sendSignal(cownref, GSN_DEBUG_SIG, signal, 9, JBA); - return; + line = __LINE__; + logWord = ZNEXT_MBYTE_TYPE; + crash_msg = "end of log wo/ having found last GCI"; + goto crash; }//if }//if /*---------------------------------------------------------------------------*/ @@ -14938,19 +14936,9 @@ void Dblqh::execSr(Signal* signal) /*---------------------------------------------------------------------------*/ /* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */ /*---------------------------------------------------------------------------*/ - signal->theData[0] = RNIL; - signal->theData[1] = logPartPtr.i; - Uint32 tmp = logFilePtr.p->fileName[3]; - tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX. - signal->theData[2] = tmp; - signal->theData[3] = logFilePtr.p->fileNo; - signal->theData[4] = logFilePtr.p->currentMbyte; - signal->theData[5] = logFilePtr.p->currentFilepage; - signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]; - signal->theData[7] = logWord; - signal->theData[8] = __LINE__; - sendSignal(cownref, GSN_DEBUG_SIG, signal, 9, JBA); - return; + line = __LINE__; + crash_msg = "Invalid logword"; + goto crash; break; }//switch /*---------------------------------------------------------------------------*/ @@ -14958,6 +14946,35 @@ void Dblqh::execSr(Signal* signal) // that we reach a new page. /*---------------------------------------------------------------------------*/ } while (1); + return; + +crash: + signal->theData[0] = RNIL; + signal->theData[1] = logPartPtr.i; + Uint32 tmp = logFilePtr.p->fileName[3]; + tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX. + signal->theData[2] = tmp; + signal->theData[3] = logFilePtr.p->fileNo; + signal->theData[4] = logFilePtr.p->currentMbyte; + signal->theData[5] = logFilePtr.p->currentFilepage; + signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX]; + signal->theData[7] = logWord; + signal->theData[8] = line; + + char buf[255]; + BaseString::snprintf(buf, sizeof(buf), + "Error while reading REDO log. from %d\n" + "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d : %s", + signal->theData[8], + signal->theData[2], + signal->theData[3], + signal->theData[4], + signal->theData[5], + signal->theData[6], + signal->theData[7], + crash_msg ? crash_msg : ""); + + progError(__LINE__, NDBD_EXIT_SR_REDOLOG, buf); }//Dblqh::execSr() /*---------------------------------------------------------------------------*/ @@ -14973,8 +14990,8 @@ void Dblqh::execDEBUG_SIG(Signal* signal) UintR tdebug; jamEntry(); - logPagePtr.i = signal->theData[0]; - tdebug = logPagePtr.p->logPageWord[0]; + //logPagePtr.i = signal->theData[0]; + //tdebug = logPagePtr.p->logPageWord[0]; char buf[100]; BaseString::snprintf(buf, 100, diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index ac7fca9cf93..bf6ce7129ba 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -720,7 +720,7 @@ public: // Index data - bool isIndexOp; // Used to mark on-going TcKeyReq as indx table access + Uint8 isIndexOp; // Used to mark on-going TcKeyReq as indx table access bool indexOpReturn; UintR noIndexOp; // No outstanding index ops @@ -808,7 +808,7 @@ public: UintR savedState[LqhKeyConf::SignalLength]; // Index data - bool isIndexOp; // Used to mark on-going TcKeyReq as index table access + Uint8 isIndexOp; // Used to mark on-going TcKeyReq as index table access UintR indexOp; UintR currentIndexId; UintR attrInfoLen; diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 71f3aff05d4..dda743616f4 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -1775,8 +1775,7 @@ void Dbtc::execKEYINFO(Signal* signal) apiConnectptr.i = signal->theData[0]; tmaxData = 20; if (apiConnectptr.i >= capiConnectFilesize) { - jam(); - warningHandlerLab(signal, __LINE__); + TCKEY_abort(signal, 18); return; }//if ptrAss(apiConnectptr, apiConnectRecord); @@ -1785,9 +1784,7 @@ void Dbtc::execKEYINFO(Signal* signal) compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2]; compare_transid1 = compare_transid1 | compare_transid2; if (compare_transid1 != 0) { - jam(); - printState(signal, 10); - sendSignalErrorRefuseLab(signal); + TCKEY_abort(signal, 19); return; }//if switch (apiConnectptr.p->apiConnectstate) { @@ -2531,7 +2528,7 @@ void Dbtc::execTCKEYREQ(Signal* signal) Uint32 TstartFlag = tcKeyReq->getStartFlag(Treqinfo); Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo); - bool isIndexOp = regApiPtr->isIndexOp; + Uint8 isIndexOp = regApiPtr->isIndexOp; bool isIndexOpReturn = regApiPtr->indexOpReturn; regApiPtr->isIndexOp = false; // Reset marker regApiPtr->m_exec_flag |= TexecFlag; @@ -3277,7 +3274,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal, sig1 = regCachePtr->fragmentid + (regTcPtr->tcNodedata[1] << 16); sig2 = regApiPtr->transid[0]; sig3 = regApiPtr->transid[1]; - sig4 = regApiPtr->ndbapiBlockref; + sig4 = (regTcPtr->isIndexOp == 2) ? reference() : regApiPtr->ndbapiBlockref; sig5 = regTcPtr->clientData; sig6 = regCachePtr->scanInfo; @@ -8619,6 +8616,7 @@ void Dbtc::execSCAN_TABREQ(Signal* signal) // left over from simple/dirty read } else { jam(); + jamLine(transP->apiConnectstate); errCode = ZSTATE_ERROR; goto SCAN_TAB_error_no_state_change; } @@ -12036,14 +12034,18 @@ void Dbtc::readIndexTable(Signal* signal, opType == ZREAD ? ZREAD : ZREAD_EX); TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0); - BlockReference originalReceiver = regApiPtr->ndbapiBlockref; - regApiPtr->ndbapiBlockref = reference(); // Send result to me tcKeyReq->senderData = indexOp->indexOpId; indexOp->indexOpState = IOS_INDEX_ACCESS; regApiPtr->executingIndexOp = regApiPtr->accumulatingIndexOp; regApiPtr->accumulatingIndexOp = RNIL; - regApiPtr->isIndexOp = true; + regApiPtr->isIndexOp = 2; + if (ERROR_INSERTED(8037)) + { + ndbout_c("shifting index version"); + tcKeyReq->tableSchemaVersion = ~(Uint32)indexOp->tcIndxReq.tableSchemaVersion; + } + Uint32 remainingKey = indexOp->keyInfo.getSize(); bool moreKeyData = indexOp->keyInfo.first(keyIter); // *********** KEYINFO in TCKEYREQ *********** @@ -12062,21 +12064,13 @@ void Dbtc::readIndexTable(Signal* signal, ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0); ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0); EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength); - - /** - * "Fool" TC not to start commiting transaction since it always will - * have one outstanding lqhkeyreq - * This is later decreased when the index read is complete - */ - regApiPtr->lqhkeyreqrec++; + jamEntry(); - /** - * Remember ptr to index read operation - * (used to set correct save point id on index operation later) - */ - indexOp->indexReadTcConnect = regApiPtr->lastTcConnect; + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + goto err; + } - jamEntry(); // *********** KEYINFO *********** if (moreKeyData) { jam(); @@ -12096,6 +12090,10 @@ void Dbtc::readIndexTable(Signal* signal, EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal, KeyInfo::HeaderLength + KeyInfo::DataLength); jamEntry(); + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + goto err; + } dataPos = 0; dataPtr = (Uint32 *) &keyInfo->keyData; } @@ -12106,10 +12104,32 @@ void Dbtc::readIndexTable(Signal* signal, EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal, KeyInfo::HeaderLength + dataPos); jamEntry(); + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + goto err; + } } } - regApiPtr->ndbapiBlockref = originalReceiver; // reset original receiver + /** + * "Fool" TC not to start commiting transaction since it always will + * have one outstanding lqhkeyreq + * This is later decreased when the index read is complete + */ + regApiPtr->lqhkeyreqrec++; + + /** + * Remember ptr to index read operation + * (used to set correct save point id on index operation later) + */ + indexOp->indexReadTcConnect = regApiPtr->lastTcConnect; + +done: + return; + +err: + jam(); + goto done; } /** @@ -12160,7 +12180,7 @@ void Dbtc::executeIndexOperation(Signal* signal, tcKeyReq->transId2 = regApiPtr->transid[1]; tcKeyReq->senderData = tcIndxReq->senderData; // Needed for TRANSID_AI to API indexOp->indexOpState = IOS_INDEX_OPERATION; - regApiPtr->isIndexOp = true; + regApiPtr->isIndexOp = 1; regApiPtr->executingIndexOp = indexOp->indexOpId;; regApiPtr->noIndexOp++; // Increase count @@ -12233,9 +12253,16 @@ void Dbtc::executeIndexOperation(Signal* signal, const Uint32 currSavePointId = regApiPtr->currSavePointId; regApiPtr->currSavePointId = tmp.p->savePointId; EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength); + jamEntry(); + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + regApiPtr->currSavePointId = currSavePointId; - jamEntry(); // *********** KEYINFO *********** if (moreKeyData) { jam(); @@ -12256,6 +12283,13 @@ void Dbtc::executeIndexOperation(Signal* signal, EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal, KeyInfo::HeaderLength + KeyInfo::DataLength); jamEntry(); + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPos = 0; dataPtr = (Uint32 *) &keyInfo->keyData; } @@ -12266,6 +12300,12 @@ void Dbtc::executeIndexOperation(Signal* signal, EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal, KeyInfo::HeaderLength + dataPos); jamEntry(); + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } } } @@ -12295,6 +12335,13 @@ void Dbtc::executeIndexOperation(Signal* signal, EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal, AttrInfo::HeaderLength + AttrInfo::DataLength); jamEntry(); + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + attrInfoPos = 0; dataPtr = (Uint32 *) &attrInfo->attrData; } @@ -12694,9 +12741,16 @@ void Dbtc::insertIntoIndexTable(Signal* signal, const Uint32 currSavePointId = regApiPtr->currSavePointId; regApiPtr->currSavePointId = opRecord->savePointId; EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength); + jamEntry(); + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + regApiPtr->currSavePointId = currSavePointId; tcConnectptr.p->currentIndexId = indexData->indexId; - jamEntry(); // *********** KEYINFO *********** if (moreKeyData) { @@ -12726,6 +12780,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal, KeyInfo::HeaderLength + KeyInfo::DataLength); jamEntry(); #endif + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } @@ -12761,6 +12821,13 @@ void Dbtc::insertIntoIndexTable(Signal* signal, KeyInfo::HeaderLength + KeyInfo::DataLength); jamEntry(); #endif + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } @@ -12778,6 +12845,11 @@ void Dbtc::insertIntoIndexTable(Signal* signal, KeyInfo::HeaderLength + dataPos); jamEntry(); #endif + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } } } @@ -12813,6 +12885,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal, AttrInfo::HeaderLength + AttrInfo::DataLength); jamEntry(); #endif + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPtr = (Uint32 *) &attrInfo->attrData; attrInfoPos = 0; } @@ -12849,6 +12927,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal, AttrInfo::HeaderLength + AttrInfo::DataLength); jamEntry(); #endif + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPtr = (Uint32 *) &attrInfo->attrData; attrInfoPos = 0; } @@ -12994,9 +13078,16 @@ void Dbtc::deleteFromIndexTable(Signal* signal, const Uint32 currSavePointId = regApiPtr->currSavePointId; regApiPtr->currSavePointId = opRecord->savePointId; EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength); + jamEntry(); + + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + regApiPtr->currSavePointId = currSavePointId; tcConnectptr.p->currentIndexId = indexData->indexId; - jamEntry(); // *********** KEYINFO *********** if (moreKeyData) { @@ -13027,6 +13118,12 @@ void Dbtc::deleteFromIndexTable(Signal* signal, KeyInfo::HeaderLength + KeyInfo::DataLength); jamEntry(); #endif + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } @@ -13063,6 +13160,12 @@ void Dbtc::deleteFromIndexTable(Signal* signal, KeyInfo::HeaderLength + KeyInfo::DataLength); jamEntry(); #endif + if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING)) + { + jam(); + return; + } + dataPtr = (Uint32 *) &keyInfo->keyData; dataPos = 0; } diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index f83f21f14d8..13c0bad9c7a 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -1113,14 +1113,16 @@ Dbtup::updateStartLab(Signal* signal, regOperPtr->pageOffset, &cinBuffer[0], regOperPtr->attrinbufLen); - if (retValue == -1) { - tupkeyErrorLab(signal); - return -1; - }//if } else { jam(); retValue = interpreterStartLab(signal, pagePtr, regOperPtr->pageOffset); }//if + + if (retValue == -1) { + tupkeyErrorLab(signal); + return -1; + }//if + ndbrequire(regOperPtr->tupVersion != ZNIL); pagePtr->pageWord[regOperPtr->pageOffset + 1] = regOperPtr->tupVersion; if (regTabPtr->checksumIndicator) { diff --git a/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp b/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp index 9722aa437c0..8a18fddae19 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp @@ -184,24 +184,28 @@ void Dbtup::allocConsPages(Uint32 noOfPagesToAllocate, /* PROPER AMOUNT OF PAGES WERE NOT FOUND. FIND AS MUCH AS */ /* POSSIBLE. */ /* ---------------------------------------------------------------- */ - for (Uint32 j = firstListToCheck; (Uint32)~j; j--) { + if (firstListToCheck) + { ljam(); - if (cfreepageList[j] != RNIL) { + for (Uint32 j = firstListToCheck - 1; (Uint32)~j; j--) { ljam(); + if (cfreepageList[j] != RNIL) { + ljam(); /* ---------------------------------------------------------------- */ /* SOME AREA WAS FOUND, ALLOCATE ALL OF IT. */ /* ---------------------------------------------------------------- */ - allocPageRef = cfreepageList[j]; - removeCommonArea(allocPageRef, j); - noOfPagesAllocated = 1 << j; - findFreeLeftNeighbours(allocPageRef, noOfPagesAllocated, - noOfPagesToAllocate); - findFreeRightNeighbours(allocPageRef, noOfPagesAllocated, - noOfPagesToAllocate); - - return; - }//if - }//for + allocPageRef = cfreepageList[j]; + removeCommonArea(allocPageRef, j); + noOfPagesAllocated = 1 << j; + findFreeLeftNeighbours(allocPageRef, noOfPagesAllocated, + noOfPagesToAllocate); + findFreeRightNeighbours(allocPageRef, noOfPagesAllocated, + noOfPagesToAllocate); + + return; + }//if + }//for + } /* ---------------------------------------------------------------- */ /* NO FREE AREA AT ALL EXISTED. RETURN ZERO PAGES */ /* ---------------------------------------------------------------- */ diff --git a/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp index acdb73704cb..0bb7c8a1e41 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp @@ -397,12 +397,12 @@ void Dbtup::allocMoreFragPages(Fragrecord* const regFragPtr) Uint32 noAllocPages = regFragPtr->noOfPagesToGrow >> 3; // 12.5% noAllocPages += regFragPtr->noOfPagesToGrow >> 4; // 6.25% noAllocPages += 2; - regFragPtr->noOfPagesToGrow += noAllocPages; /* -----------------------------------------------------------------*/ // We will grow by 18.75% plus two more additional pages to grow // a little bit quicker in the beginning. /* -----------------------------------------------------------------*/ - allocFragPages(regFragPtr, noAllocPages); + Uint32 allocated = allocFragPages(regFragPtr, noAllocPages); + regFragPtr->noOfPagesToGrow += allocated; }//Dbtup::allocMoreFragPages() Uint32 Dbtup::leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr currPageRangePtr) diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index e6bb4d4f14f..fe6caf04d8c 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -181,10 +181,9 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) case SystemError::CopyFragRefError: BaseString::snprintf(buf, sizeof(buf), - "Node %d killed this node because " - "it could not copy a fragment during node restart. " - "Copy fragment error code: %u.", - killingNode, data1); + "Killed by node %d as " + "copyfrag failed, error: %u", + killingNode, data1); break; default: @@ -2043,6 +2042,11 @@ void Ndbcntr::execSET_VAR_REQ(Signal* signal) { void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{ NodeStateRep * const stateRep = (NodeStateRep *)&signal->theData[0]; + if (newState.startLevel == NodeState::SL_STARTED) + { + CRASH_INSERTION(1000); + } + stateRep->nodeState = newState; stateRep->nodeState.masterNodeId = cmasterNodeId; stateRep->nodeState.setNodeGroup(c_nodeGroup); @@ -2843,7 +2847,7 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){ cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB); } } - + signal->theData[0] = NDB_LE_NDBStartCompleted; signal->theData[1] = NDB_VERSION; cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB); diff --git a/ndb/src/kernel/error/ndbd_exit_codes.c b/ndb/src/kernel/error/ndbd_exit_codes.c index 07b276346a0..cb3272b38a9 100644 --- a/ndb/src/kernel/error/ndbd_exit_codes.c +++ b/ndb/src/kernel/error/ndbd_exit_codes.c @@ -247,7 +247,7 @@ int ndbd_exit_string(int err_no, char *str, unsigned int size) ndbd_exit_classification cl; ndbd_exit_status st; const char *msg = ndbd_exit_message(err_no, &cl); - if (msg[0] != '\0') + if (msg[0] != '\0' && cl != XUE) { const char *cl_msg = ndbd_exit_classification_message(cl, &st); const char *st_msg = ndbd_exit_status_message(st); diff --git a/ndb/src/kernel/vm/DLHashTable2.hpp b/ndb/src/kernel/vm/DLHashTable2.hpp index 6b166331631..1018b053e2a 100644 --- a/ndb/src/kernel/vm/DLHashTable2.hpp +++ b/ndb/src/kernel/vm/DLHashTable2.hpp @@ -147,6 +147,8 @@ public: * @param iter - An "uninitialized" iterator */ bool next(Uint32 bucket, Iterator & iter) const; + + inline bool isEmpty() const { Iterator iter; return ! first(iter); } private: Uint32 mask; diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 4428b158b6b..9bf19dda3a4 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -1389,7 +1389,7 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[], MGM_END() }; CHECK_HANDLE(handle, -1); - + const char *hostname= ndb_mgm_get_connected_host(handle); int port= ndb_mgm_get_connected_port(handle); SocketClient s(hostname, port); @@ -1411,19 +1411,20 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[], } args.put("filter", tmp.c_str()); } - + int tmp = handle->socket; handle->socket = sockfd; - + const Properties *reply; reply = ndb_mgm_call(handle, stat_reply, "listen event", &args); - + handle->socket = tmp; - + if(reply == NULL) { close(sockfd); CHECK_REPLY(reply, -1); } + delete reply; return sockfd; } diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp index a90d5658506..2472a434590 100644 --- a/ndb/src/mgmapi/ndb_logevent.cpp +++ b/ndb/src/mgmapi/ndb_logevent.cpp @@ -68,6 +68,13 @@ ndb_mgm_create_logevent_handle(NdbMgmHandle mh, } extern "C" +int +ndb_logevent_get_fd(const NdbLogEventHandle h) +{ + return h->socket; +} + +extern "C" void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle * h) { if( !h ) diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 58b98671b14..ba68f6e4f0a 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -173,8 +173,15 @@ private: bool rep_connected; #endif struct NdbThread* m_event_thread; + NdbMutex *m_print_mutex; }; +struct event_thread_param { + NdbMgmHandle *m; + NdbMutex **p; +}; + +NdbMutex* print_mutex; /* * Facade object for CommandInterpreter @@ -395,6 +402,7 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose) m_connected= false; m_event_thread= 0; try_reconnect = 0; + m_print_mutex= NdbMutex_Create(); #ifdef HAVE_GLOBAL_REPLICATION rep_host = NULL; m_repserver = NULL; @@ -408,6 +416,7 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose) CommandInterpreter::~CommandInterpreter() { disconnect(); + NdbMutex_Destroy(m_print_mutex); } static bool @@ -444,11 +453,13 @@ CommandInterpreter::printError() static int do_event_thread; static void* -event_thread_run(void* m) +event_thread_run(void* p) { DBUG_ENTER("event_thread_run"); - NdbMgmHandle handle= *(NdbMgmHandle*)m; + struct event_thread_param param= *(struct event_thread_param*)p; + NdbMgmHandle handle= *(param.m); + NdbMutex* printmutex= *(param.p); int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP, 1, NDB_MGM_EVENT_CATEGORY_STARTUP, @@ -466,7 +477,11 @@ event_thread_run(void* m) { const char ping_token[]= "<PING>"; if (memcmp(ping_token,tmp,sizeof(ping_token)-1)) - ndbout << tmp; + if(tmp && strlen(tmp)) + { + Guard g(printmutex); + ndbout << tmp; + } } } while(do_event_thread); NDB_CLOSE_SOCKET(fd); @@ -519,8 +534,11 @@ CommandInterpreter::connect() assert(m_event_thread == 0); assert(do_event_thread == 0); do_event_thread= 0; + struct event_thread_param p; + p.m= &m_mgmsrv2; + p.p= &m_print_mutex; m_event_thread = NdbThread_Create(event_thread_run, - (void**)&m_mgmsrv2, + (void**)&p, 32768, "CommandInterpreted_event_thread", NDB_THREAD_PRIO_LOW); @@ -607,6 +625,7 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect, int result= execute_impl(_line); if (error) *error= m_error; + return result; } @@ -686,6 +705,7 @@ CommandInterpreter::execute_impl(const char *_line) DBUG_RETURN(true); if (strcasecmp(firstToken, "SHOW") == 0) { + Guard g(m_print_mutex); executeShow(allAfterFirstToken); DBUG_RETURN(true); } @@ -920,6 +940,7 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun, ndbout_c("Trying to start all nodes of system."); ndbout_c("Use ALL STATUS to see the system start-up phases."); } else { + Guard g(m_print_mutex); struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv); if(cl == 0){ ndbout_c("Unable get status from management server"); @@ -1224,6 +1245,7 @@ CommandInterpreter::executeShow(char* parameters) if(it == 0){ ndbout_c("Unable to create config iterator"); + ndb_mgm_destroy_configuration(conf); return; } NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it); @@ -1270,6 +1292,7 @@ CommandInterpreter::executeShow(char* parameters) print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0); print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0); // ndbout << helpTextShow; + ndb_mgm_destroy_configuration(conf); return; } else if (strcasecmp(parameters, "PROPERTIES") == 0 || strcasecmp(parameters, "PROP") == 0) { diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 69c0286a1de..5fabb84adb7 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -77,7 +77,6 @@ }\ } -extern int global_flag_send_heartbeat_now; extern int g_no_nodeid_checks; extern my_bool opt_core; @@ -1455,6 +1454,12 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort) #include <ClusterMgr.hpp> +void +MgmtSrvr::updateStatus() +{ + theFacade->theClusterMgr->forceHB(); +} + int MgmtSrvr::status(int nodeId, ndb_mgm_node_status * _status, @@ -2153,7 +2158,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId, if (found_matching_type && !found_free_node) { // we have a temporary error which might be due to that // we have got the latest connect status from db-nodes. Force update. - global_flag_send_heartbeat_now= 1; + updateStatus(); } BaseString type_string, type_c_string; @@ -2507,7 +2512,7 @@ MgmtSrvr::Allocated_resources::~Allocated_resources() if (!m_reserved_nodes.isclear()) { m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes); // node has been reserved, force update signal to ndb nodes - global_flag_send_heartbeat_now= 1; + m_mgmsrv.updateStatus(); char tmp_str[128]; m_mgmsrv.m_reserved_nodes.getText(tmp_str); diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index 187f225470a..17debb19f50 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -490,6 +490,8 @@ public: void get_connected_nodes(NodeBitmask &connected_nodes) const; SocketServer *get_socket_server() { return m_socket_server; } + void updateStatus(); + //************************************************************************** private: //************************************************************************** diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 0524aba4c32..7f5b0e29442 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -982,6 +982,7 @@ printNodeStatus(OutputStream *output, MgmtSrvr &mgmsrv, enum ndb_mgm_node_type type) { NodeId nodeId = 0; + mgmsrv.updateStatus(); while(mgmsrv.getNextNodeId(&nodeId, type)) { enum ndb_mgm_node_status status; Uint32 startPhase = 0, diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index fbff57d3168..475561af225 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -37,7 +37,7 @@ #include <mgmapi_configuration.hpp> #include <mgmapi_config_parameters.h> -int global_flag_send_heartbeat_now= 0; +//#define DEBUG_REG // Just a C wrapper for threadMain extern "C" @@ -67,6 +67,8 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade): DBUG_ENTER("ClusterMgr::ClusterMgr"); ndbSetOwnVersion(); clusterMgrThreadMutex = NdbMutex_Create(); + waitForHBCond= NdbCondition_Create(); + waitingForHB= false; noOfAliveNodes= 0; noOfConnectedNodes= 0; theClusterMgrThread= 0; @@ -77,7 +79,8 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade): ClusterMgr::~ClusterMgr() { DBUG_ENTER("ClusterMgr::~ClusterMgr"); - doStop(); + doStop(); + NdbCondition_Destroy(waitForHBCond); NdbMutex_Destroy(clusterMgrThreadMutex); DBUG_VOID_RETURN; } @@ -164,6 +167,70 @@ ClusterMgr::doStop( ){ } void +ClusterMgr::forceHB() +{ + theFacade.lock_mutex(); + + if(waitingForHB) + { + NdbCondition_WaitTimeout(waitForHBCond, theFacade.theMutexPtr, 1000); + theFacade.unlock_mutex(); + return; + } + + waitingForHB= true; + + NodeBitmask ndb_nodes; + ndb_nodes.clear(); + waitForHBFromNodes.clear(); + for(Uint32 i = 0; i < MAX_NODES; i++) + { + if(!theNodes[i].defined) + continue; + if(theNodes[i].m_info.m_type == NodeInfo::DB) + { + ndb_nodes.set(i); + const ClusterMgr::Node &node= getNodeInfo(i); + waitForHBFromNodes.bitOR(node.m_state.m_connected_nodes); + } + } + waitForHBFromNodes.bitAND(ndb_nodes); + +#ifdef DEBUG_REG + char buf[128]; + ndbout << "Waiting for HB from " << waitForHBFromNodes.getText(buf) << endl; +#endif + NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); + + signal.theVerId_signalNumber = GSN_API_REGREQ; + signal.theReceiversBlockNumber = QMGR; + signal.theTrace = 0; + signal.theLength = ApiRegReq::SignalLength; + + ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend()); + req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId()); + req->version = NDB_VERSION; + + int nodeId= 0; + for(int i=0; + NodeBitmask::NotFound!=(nodeId= waitForHBFromNodes.find(i)); + i= nodeId+1) + { +#ifdef DEBUG_REG + ndbout << "FORCE HB to " << nodeId << endl; +#endif + theFacade.sendSignalUnCond(&signal, nodeId); + } + + NdbCondition_WaitTimeout(waitForHBCond, theFacade.theMutexPtr, 1000); + waitingForHB= false; +#ifdef DEBUG_REG + ndbout << "Still waiting for HB from " << waitForHBFromNodes.getText(buf) << endl; +#endif + theFacade.unlock_mutex(); +} + +void ClusterMgr::threadMain( ){ NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId())); @@ -184,9 +251,6 @@ ClusterMgr::threadMain( ){ /** * Start of Secure area for use of Transporter */ - int send_heartbeat_now= global_flag_send_heartbeat_now; - global_flag_send_heartbeat_now= 0; - theFacade.lock_mutex(); for (int i = 1; i < MAX_NODES; i++){ /** @@ -209,8 +273,7 @@ ClusterMgr::threadMain( ){ } theNode.hbCounter += timeSlept; - if (theNode.hbCounter >= theNode.hbFrequency || - send_heartbeat_now) { + if (theNode.hbCounter >= theNode.hbFrequency) { /** * It is now time to send a new Heartbeat */ @@ -226,7 +289,7 @@ ClusterMgr::threadMain( ){ if (theNode.m_info.m_type == NodeInfo::REP) { signal.theReceiversBlockNumber = API_CLUSTERMGR; } -#if 0 +#ifdef DEBUG_REG ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId); #endif theFacade.sendSignalUnCond(&signal, nodeId); @@ -278,7 +341,7 @@ ClusterMgr::execAPI_REGREQ(const Uint32 * theData){ const ApiRegReq * const apiRegReq = (ApiRegReq *)&theData[0]; const NodeId nodeId = refToNode(apiRegReq->ref); -#if 0 +#ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGREQ from node %d", nodeId); #endif @@ -319,7 +382,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0]; const NodeId nodeId = refToNode(apiRegConf->qmgrRef); -#if 0 +#ifdef DEBUG_REG ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId); #endif @@ -351,6 +414,17 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){ if (node.m_info.m_type != NodeInfo::REP) { node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50; } + + if(waitingForHB) + { + waitForHBFromNodes.clear(nodeId); + + if(waitForHBFromNodes.isclear()) + { + waitingForHB= false; + NdbCondition_Broadcast(waitForHBCond); + } + } } void @@ -379,6 +453,10 @@ ClusterMgr::execAPI_REGREF(const Uint32 * theData){ default: break; } + + waitForHBFromNodes.clear(nodeId); + if(waitForHBFromNodes.isclear()) + NdbCondition_Signal(waitForHBCond); } void diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp index 1a1e622a889..d2bcc52f7e8 100644 --- a/ndb/src/ndbapi/ClusterMgr.hpp +++ b/ndb/src/ndbapi/ClusterMgr.hpp @@ -49,7 +49,9 @@ public: void doStop(); void startThread(); - + + void forceHB(); + private: void threadMain(); @@ -85,7 +87,11 @@ private: Uint32 noOfConnectedNodes; Node theNodes[MAX_NODES]; NdbThread* theClusterMgrThread; - + + NodeBitmask waitForHBFromNodes; // used in forcing HBs + NdbCondition* waitForHBCond; + bool waitingForHB; + /** * Used for controlling start/stop of the thread */ diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 90e3a63c53d..c5a0ebbaf60 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -475,6 +475,8 @@ int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend) idx = m_current_api_receiver; last = m_api_receivers_count; + + Uint32 timeout = tp->m_waitfor_timeout; do { if(theError.code){ @@ -502,7 +504,7 @@ int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend) */ theNdb->theImpl->theWaiter.m_node = nodeId; theNdb->theImpl->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + int return_code = theNdb->receiveResponse(3*timeout); if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) { continue; } else { @@ -1365,6 +1367,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, return -1; Uint32 seq = theNdbCon->theNodeSequence; Uint32 nodeId = theNdbCon->theDBnode; + Uint32 timeout = tp->m_waitfor_timeout; if(seq == tp->getNodeSequence(nodeId) && !send_next_scan_ordered(s_idx, forceSend)){ Uint32 tmp = m_sent_receivers_count; @@ -1372,7 +1375,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, while(m_sent_receivers_count > 0 && !theError.code){ theNdb->theImpl->theWaiter.m_node = nodeId; theNdb->theImpl->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + int return_code = theNdb->receiveResponse(3*timeout); if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) { continue; } @@ -1513,6 +1516,8 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){ return -1; } + Uint32 timeout = tp->m_waitfor_timeout; + /** * Wait for outstanding */ @@ -1520,7 +1525,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){ { theNdb->theImpl->theWaiter.m_node = nodeId; theNdb->theImpl->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + int return_code = theNdb->receiveResponse(3*timeout); switch(return_code){ case 0: break; @@ -1590,7 +1595,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){ { theNdb->theImpl->theWaiter.m_node = nodeId; theNdb->theImpl->theWaiter.m_state = WAIT_SCAN; - int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT); + int return_code = theNdb->receiveResponse(3*timeout); switch(return_code){ case 0: break; diff --git a/ndb/test/include/NDBT_Tables.hpp b/ndb/test/include/NDBT_Tables.hpp index fb0df8aa35b..a6973861af8 100644 --- a/ndb/test/include/NDBT_Tables.hpp +++ b/ndb/test/include/NDBT_Tables.hpp @@ -42,6 +42,8 @@ public: static const NdbDictionary::Table* getTable(int _num); static int getNumTables(); + static const char** getIndexes(const char* table); + private: static const NdbDictionary::Table* tableWithPkSize(const char* _nam, Uint32 pkSize); }; diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index b992d492ad6..ba05bbad7bb 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -1022,8 +1022,8 @@ int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary:: if (!pTab->equal(*pTab2)){ g_err << "equal failed" << endl; - g_info << *pTab; - g_info << *pTab2; + g_info << *(NDBT_Table*)pTab; // gcc-4.1.2 + g_info << *(NDBT_Table*)pTab2; return NDBT_FAILED; } return NDBT_OK; @@ -1033,7 +1033,7 @@ int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; - g_info << *pTab; + g_info << *(NDBT_Table*)pTab; // Try to create table in db if (pTab->createTableInDb(pNdb) != 0){ return NDBT_FAILED; @@ -1890,6 +1890,52 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step) // replace by the Retrieved table pTab = pTab2; + // create indexes + const char** indlist = NDBT_Tables::getIndexes(tabName); + uint indnum = 0; + while (*indlist != 0) { + uint count = 0; + try_create_index: + count++; + if (count == 1) + g_info << "2: create index " << indnum << " " << *indlist << endl; + NdbDictionary::Index ind; + char indName[200]; + sprintf(indName, "%s_X%u", tabName, indnum); + ind.setName(indName); + ind.setTable(tabName); + if (strcmp(*indlist, "UNIQUE") == 0) { + ind.setType(NdbDictionary::Index::UniqueHashIndex); + ind.setLogging(pTab->getLogging()); + } else if (strcmp(*indlist, "ORDERED") == 0) { + ind.setType(NdbDictionary::Index::OrderedIndex); + ind.setLogging(false); + } else { + assert(false); + } + const char** indtemp = indlist; + while (*++indtemp != 0) { + ind.addColumn(*indtemp); + } + if (pDic->createIndex(ind) != 0) { + const NdbError err = pDic->getNdbError(); + if (count == 1) + g_err << "2: " << indName << ": create failed: " << err << endl; + if (err.code != 711) { + result = NDBT_FAILED; + break; + } + NdbSleep_MilliSleep(myRandom48(maxsleep)); + goto try_create_index; + } + indlist = ++indtemp; + indnum++; + } + if (result == NDBT_FAILED) + break; + + uint indcount = indnum; + int records = myRandom48(ctx->getNumRecords()); g_info << "2: load " << records << " records" << endl; HugoTransactions hugoTrans(*pTab); @@ -1901,6 +1947,32 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step) } NdbSleep_MilliSleep(myRandom48(maxsleep)); + // drop indexes + indnum = 0; + while (indnum < indcount) { + uint count = 0; + try_drop_index: + count++; + if (count == 1) + g_info << "2: drop index " << indnum << endl; + char indName[200]; + sprintf(indName, "%s_X%u", tabName, indnum); + if (pDic->dropIndex(indName, tabName) != 0) { + const NdbError err = pDic->getNdbError(); + if (count == 1) + g_err << "2: " << indName << ": drop failed: " << err << endl; + if (err.code != 711) { + result = NDBT_FAILED; + break; + } + NdbSleep_MilliSleep(myRandom48(maxsleep)); + goto try_drop_index; + } + indnum++; + } + if (result == NDBT_FAILED) + break; + g_info << "2: drop" << endl; { uint count = 0; diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index 5785db232c4..c25aae55897 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -1199,6 +1199,48 @@ int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int +runBug21384(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + NdbRestarter restarter; + + int loops = ctx->getNumLoops(); + const int rows = ctx->getNumRecords(); + const int batchsize = ctx->getProperty("BatchSize", 50); + + while (loops--) + { + if(restarter.insertErrorInAllNodes(8037) != 0) + { + g_err << "Failed to error insert(8037)" << endl; + return NDBT_FAILED; + } + + if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) == 0) + { + g_err << "Index succeded (it should have failed" << endl; + return NDBT_FAILED; + } + + if(restarter.insertErrorInAllNodes(0) != 0) + { + g_err << "Failed to error insert(0)" << endl; + return NDBT_FAILED; + } + + if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) != 0){ + g_err << "Index read failed" << endl; + return NDBT_FAILED; + } + } + + return NDBT_OK; +} + + + NDBT_TESTSUITE(testIndex); TESTCASE("CreateAll", "Test that we can create all various indexes on each table\n" @@ -1512,6 +1554,16 @@ TESTCASE("UniqueNull", FINALIZER(createPkIndex_Drop); FINALIZER(runClearTable); } +TESTCASE("Bug21384", + "Test that unique indexes and nulls"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runBug21384); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testIndex); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp index 30f7aca9b06..8a0100ff3e4 100644 --- a/ndb/test/ndbapi/testSystemRestart.cpp +++ b/ndb/test/ndbapi/testSystemRestart.cpp @@ -1121,6 +1121,46 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int +runBug21536(NDBT_Context* ctx, NDBT_Step* step) +{ + NdbRestarter restarter; + const Uint32 nodeCount = restarter.getNumDbNodes(); + if(nodeCount != 2){ + g_info << "Bug21536 - 2 nodes to test" << endl; + return NDBT_OK; + } + + int node1 = restarter.getDbNodeId(rand() % nodeCount); + int node2 = restarter.getRandomNodeSameNodeGroup(node1, rand()); + + if (node1 == -1 || node2 == -1) + return NDBT_OK; + + int result = NDBT_OK; + do { + CHECK(restarter.restartOneDbNode(node1, false, true, true) == 0); + CHECK(restarter.waitNodesNoStart(&node1, 1) == 0); + CHECK(restarter.insertErrorInNode(node1, 1000) == 0); + int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 }; + CHECK(restarter.dumpStateOneNode(node1, val2, 2) == 0); + CHECK(restarter.startNodes(&node1, 1) == 0); + restarter.waitNodesStartPhase(&node1, 1, 3, 120); + CHECK(restarter.waitNodesNoStart(&node1, 1) == 0); + + CHECK(restarter.restartOneDbNode(node2, true, true, true) == 0); + CHECK(restarter.waitNodesNoStart(&node2, 1) == 0); + CHECK(restarter.startNodes(&node1, 1) == 0); + CHECK(restarter.waitNodesStarted(&node1, 1) == 0); + CHECK(restarter.startNodes(&node2, 1) == 0); + CHECK(restarter.waitClusterStarted() == 0); + + } while(0); + + g_info << "Bug21536 finished" << endl; + + return result; +} NDBT_TESTSUITE(testSystemRestart); TESTCASE("SR1", @@ -1287,6 +1327,13 @@ TESTCASE("Bug18385", STEP(runBug18385); FINALIZER(runClearTable); } +TESTCASE("Bug21536", + "Perform partition system restart with other nodes with higher GCI"){ + INITIALIZER(runWaitStarted); + INITIALIZER(runClearTable); + STEP(runBug21536); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testSystemRestart); int main(int argc, const char** argv){ diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index cbb8a9a2574..a2edc568426 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -449,6 +449,10 @@ max-time: 1000 cmd: testNodeRestart args: -n Bug20185 T1 +max-time: 1000 +cmd: testIndex +args: -n Bug21384 + # OLD FLEX max-time: 500 cmd: flexBench diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp index 5a5fecd85c1..d72dfcc5031 100644 --- a/ndb/test/src/NDBT_Tables.cpp +++ b/ndb/test/src/NDBT_Tables.cpp @@ -799,6 +799,17 @@ NDBT_Tables::getNumTables(){ return numTestTables; } +const char** +NDBT_Tables::getIndexes(const char* table) +{ + Uint32 i = 0; + for (i = 0; indexes[i].m_table != 0; i++) { + if (strcmp(indexes[i].m_table, table) == 0) + return indexes[i].m_indexes; + } + return 0; +} + int NDBT_Tables::createAllTables(Ndb* pNdb, bool _temp, bool existsOk){ diff --git a/ndb/tools/ndb_config.cpp b/ndb/tools/ndb_config.cpp index 27ab6a182bb..135bec7ef72 100644 --- a/ndb/tools/ndb_config.cpp +++ b/ndb/tools/ndb_config.cpp @@ -145,7 +145,7 @@ struct Match struct HostMatch : public Match { - virtual int eval(NdbMgmHandle, const Iter&); + virtual int eval(const Iter&); }; struct Apply @@ -402,7 +402,7 @@ Match::eval(const Iter& iter) } int -HostMatch::eval(NdbMgmHandle h, const Iter& iter) +HostMatch::eval(const Iter& iter) { const char* valc; diff --git a/regex/CMakeLists.txt b/regex/CMakeLists.txt new file mode 100755 index 00000000000..796481a62d5 --- /dev/null +++ b/regex/CMakeLists.txt @@ -0,0 +1,5 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys}) +ADD_LIBRARY(regex debug.c regcomp.c regerror.c regexec.c regfree.c reginit.c split.c) diff --git a/regex/Makefile.am b/regex/Makefile.am index 7e8478e8123..1f496fcec62 100644 --- a/regex/Makefile.am +++ b/regex/Makefile.am @@ -25,7 +25,7 @@ re_SOURCES = split.c debug.c main.c re_LDFLAGS= @NOINST_LDFLAGS@ EXTRA_DIST = tests CHANGES COPYRIGHT WHATSNEW regexp.c \ debug.ih engine.ih main.ih regcomp.ih regerror.ih \ - regex.3 regex.7 + regex.3 regex.7 CMakeLists.txt test: re tests ./re < tests diff --git a/scripts/Makefile.am b/scripts/Makefile.am index a339ebc5b8f..dd4c133ff94 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -66,7 +66,8 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \ EXTRA_DIST = $(EXTRA_SCRIPTS) \ mysqlaccess.conf \ - mysqlbug + mysqlbug \ + make_win_bin_dist dist_pkgdata_DATA = fill_help_tables.sql mysql_fix_privilege_tables.sql diff --git a/scripts/fill_func_tables.sh b/scripts/fill_func_tables.sh index 203c730dd9a..ad5b7fbb521 100644 --- a/scripts/fill_func_tables.sh +++ b/scripts/fill_func_tables.sh @@ -1,7 +1,12 @@ -#!/usr/bin/perl +#!@PERL@ +# +# Copyright (C) 2003 MySQL AB +# For a more info consult the file COPYRIGHT distributed with this file. +# # fill_func_tables - parse ../Docs/manual.texi - -# Original version by vva +# +# Original version by Victor Vagin <vva@mysql.com> +# my $cat_name= ""; my $func_name= ""; diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist new file mode 100755 index 00000000000..cc75245e5d9 --- /dev/null +++ b/scripts/make_win_bin_dist @@ -0,0 +1,345 @@ +#!/bin/sh + +# Exit if failing to copy, we want exact specifications, not +# just "what happen to be built". +set -e + +# ---------------------------------------------------------------------- +# Read first argument that is the base name of the resulting TAR file. +# See usage() function below for a description on the arguments. +# +# NOTE: We will read the rest of the command line later on. +# NOTE: Pattern matching with "{..,..}" can't be used, not portable. +# ---------------------------------------------------------------------- + +# FIXME FIXME "debug", own build or handled here? +# FIXME FIXME add way to copy from other builds executables + +usage() +{ + echo <<EOF +Usage: make_win_bin_dist [ options ] package-base-name [ copy-defs... ] + +This is a script to run from the top of a source tree built on Windows. +The "package-base-name" argument should be something like + + mysql-noinstall-5.0.25-win32 (or winx64) + +and will be the name of the directory of the unpacked ZIP (stripping +away the "noinstall" part of the ZIP file name if any) and the base +for the resulting package name. + +Options are + + --embedded Pack the embedded server and give error if not built. + The default is to pack it if it is built. + + --no-embedded Don't pack the embedded server even if built + + --debug Pack the debug binaries and give error if not built. + + --no-debug Don't pack the debug binaries even if built + + --only-debug The target for this build was "Debug", and we just + want to replace the normal binaries with debug + versions, i.e. no separate "debug" directories. + + --exe-suffix=SUF Add a suffix to the "mysqld" binary. + +As you might want to include files of directories from other builds +(like a "mysqld-max.exe" server), you can instruct this script do copy +them in for you. This is the "copy-def" arguments, and they are of the +form + + relative-dest-name=source-name ..... + +i.e. can be something like + + bin/mysqld-max.exe=../my-max-build/sql/release/mysqld.exe + +If you specify a directory the whole directory will be copied. + +EOF + exit 1 +} + +# ---------------------------------------------------------------------- +# We need to be at the top of a source tree, check that we are +# ---------------------------------------------------------------------- + +if [ ! -d "sql" ] ; then + echo "You need to run this script from inside the source tree" + usage +fi + +# ---------------------------------------------------------------------- +# Actual argument processing, first part +# ---------------------------------------------------------------------- + +NOINST_NAME="" +TARGET="release" +PACK_EMBEDDED="" # Could be "no", "yes" or empty +PACK_DEBUG="" # Could be "no", "yes" or empty +EXE_SUFFIX="" + +for arg do + shift + case "$arg" in + --embedded) PACK_EMBEDDED="yes" ;; + --no-embedded) PACK_EMBEDDED="no" ;; + --debug) PACK_DEBUG="yes" ;; + --no-debug) PACK_DEBUG="no" ;; + --only-debug) TARGET="debug" ; PACK_DEBUG="no" ;; + --exe-suffix=*) EXE_SUFFIX=`echo "$arg" | sed -e "s,--exe-suffix=,,"` ;; + -*) + echo "Unknown argument '$arg'" + usage + ;; + *) + NOINST_NAME="$arg" + break + esac +done + +if [ x"$NOINST_NAME" = x"" ] ; then + echo "No base package name given" + usage +fi +DESTDIR=`echo $NOINST_NAME | sed 's/-noinstall-/-/'` + +if [ -e $DESTDIR ] ; then + echo "Please remove the old $DESTDIR before running this script" + usage +fi + +# ---------------------------------------------------------------------- +# Copy executables, and client DLL (FIXME why?) +# ---------------------------------------------------------------------- + +trap 'echo "Clearning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR + +mkdir $DESTDIR +mkdir $DESTDIR/bin +cp client/$TARGET/*.exe $DESTDIR/bin/ +cp extra/$TARGET/*.exe $DESTDIR/bin/ +cp myisam/$TARGET/*.exe $DESTDIR/bin/ +cp server-tools/instance-manager/$TARGET/*.exe $DESTDIR/bin/ +cp tests/$TARGET/*.exe $DESTDIR/bin/ +cp libmysql/$TARGET/*.exe $DESTDIR/bin/ +cp libmysql/$TARGET/libmysql.dll $DESTDIR/bin/ + +# FIXME really needed?! +mv $DESTDIR/bin/comp_err.exe $DESTDIR/bin/comp-err.exe + +cp sql/$TARGET/mysqld.exe $DESTDIR/bin/mysqld$EXE_SUFFIX.exe + +if [ x"$PACK_DEBUG" = "" -a -f "sql/debug/mysqld.exe" -o \ + x"$PACK_DEBUG" = "yes" ] ; then + cp sql/debug/mysqld.exe $DESTDIR/bin/mysqld-debug.exe + cp sql/debug/mysqld.pdb $DESTDIR/bin/mysqld-debug.pdb + cp sql/debug/mysqld.map $DESTDIR/bin/mysqld-debug.map +fi + +# ---------------------------------------------------------------------- +# Copy data directory, readme files etc +# ---------------------------------------------------------------------- + +cp COPYING EXCEPTIONS-CLIENT $DESTDIR/ + +# FIXME is there ever a data directory to copy? +if [ -d win/data ] ; then + cp -pR win/data $DESTDIR/data +fi + +# FIXME maybe a flag to define "release build", or do the +# check from the calling script that all these are there, +# and with the correct content. + +mkdir $DESTDIR/Docs +cp Docs/INSTALL-BINARY $DESTDIR/Docs/ +cp Docs/manual.chm $DESTDIR/Docs/ || /bin/true +cp ChangeLog $DESTDIR/Docs/ || /bin/true +cp COPYING $DESTDIR/Docs/ +cp support-files/my-*.ini $DESTDIR/ + +# ---------------------------------------------------------------------- +# These will be filled in when we enable embedded. Note that if no +# argument is given, it is copied if exists, else a check is done. +# ---------------------------------------------------------------------- + +copy_embedded() +{ + mkdir -p $DESTDIR/Embedded/DLL/release \ + $DESTDIR/Embedded/static/release + cp libmysqld/libmysqld.def $DESTDIR/include/ + cp libmysqld/$TARGET/mysqlserver.lib $DESTDIR/Embedded/static/release/ + cp libmysqld/$TARGET/libmysqld.dll $DESTDIR/Embedded/DLL/release/ + cp libmysqld/$TARGET/libmysqld.exp $DESTDIR/Embedded/DLL/release/ + cp libmysqld/$TARGET/libmysqld.lib $DESTDIR/Embedded/DLL/release/ + + if [ x"$PACK_DEBUG" = "" -a -f "libmysqld/debug/libmysqld.lib" -o \ + x"$PACK_DEBUG" = "yes" ] ; then + mkdir -p $DESTDIR/Embedded/DLL/debug + cp libmysqld/debug/libmysqld.dll $DESTDIR/Embedded/DLL/debug/ + cp libmysqld/debug/libmysqld.exp $DESTDIR/Embedded/DLL/debug/ + cp libmysqld/debug/libmysqld.lib $DESTDIR/Embedded/DLL/debug/ + fi +} + +if [ x"$PACK_EMBEDDED" = "" -a \ + -f "libmysqld/$TARGET/mysqlserver.lib" -a \ + -f "libmysqld/$TARGET/libmysqld.lib" -o \ + x"$PACK_EMBEDDED" = "yes" ] ; then + copy_embedded +fi + +# ---------------------------------------------------------------------- +# FIXME test stuff that is useless garbage? +# ---------------------------------------------------------------------- + +mkdir -p $DESTDIR/examples/libmysqltest/release +cp libmysql/mytest.c libmysql/myTest.vcproj libmysql/$TARGET/myTest.exe \ + $DESTDIR/examples/libmysqltest/ +cp libmysql/$TARGET/myTest.exe $DESTDIR/examples/libmysqltest/release/ + +if [ x"$PACK_DEBUG" = "" -a -f "libmysql/debug/myTest.exe" -o \ + x"$PACK_DEBUG" = "yes" ] ; then + mkdir -p $DESTDIR/examples/libmysqltest/debug + cp libmysql/debug/myTest.exe $DESTDIR/examples/libmysqltest/debug/ +fi + +mkdir -p $DESTDIR/examples/tests +cp tests/*.res tests/*.tst tests/*.pl tests/*.c $DESTDIR/examples/tests/ + +# ---------------------------------------------------------------------- +# FIXME why not copy it all in "include"?! +# ---------------------------------------------------------------------- + +mkdir -p $DESTDIR/include +cp include/conf*.h \ + include/mysql*.h \ + include/errmsg.h \ + include/my_alloc.h \ + include/my_getopt.h \ + include/my_sys.h \ + include/my_list.h \ + include/my_pthread.h \ + include/my_dbug.h \ + include/m_string.h \ + include/m_ctype.h \ + include/my_global.h \ + include/typelib.h $DESTDIR/include/ +cp libmysql/libmysql.def $DESTDIR/include/ + +# ---------------------------------------------------------------------- +# Client libraries, and other libraries +# FIXME why "libmysql.dll" installed both in "bin" and "lib/opt"? +# ---------------------------------------------------------------------- + +mkdir -p $DESTDIR/lib/opt +cp libmysql/$TARGET/libmysql.dll \ + libmysql/$TARGET/libmysql.lib \ + client/$TARGET/mysqlclient.lib \ + regex/$TARGET/regex.lib \ + strings/$TARGET/strings.lib \ + zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/ + +if [ x"$PACK_DEBUG" = "" -a -f "libmysql/debug/libmysql.lib" -o \ + x"$PACK_DEBUG" = "yes" ] ; then + mkdir -p $DESTDIR/lib/debug + cp libmysql/debug/libmysql.dll \ + libmysql/debug/libmysql.lib \ + client/debug/mysqlclient.lib \ + mysys/debug/mysys.lib \ + regex/debug/regex.lib \ + strings/debug/strings.lib \ + zlib/debug/zlib.lib $DESTDIR/lib/debug/ +fi + +# FIXME sort this out... +cp mysys/$TARGET/mysys.lib $DESTDIR/lib/opt/mysys_tls.lib + +# ---------------------------------------------------------------------- +# Copy the test directory +# ---------------------------------------------------------------------- + +mkdir -p $DESTDIR/mysql-test/include $DESTDIR/mysql-test/lib \ + $DESTDIR/mysql-test/r $DESTDIR/mysql-test/std_data \ + $DESTDIR/mysql-test/t +cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/ +cp mysql-test/README $DESTDIR/mysql-test/ +cp mysql-test/install_test_db.sh $DESTDIR/mysql-test/install_test_db +cp mysql-test/include/*.inc $DESTDIR/mysql-test/include/ +cp mysql-test/lib/*.pl $DESTDIR/mysql-test/lib/ +cp mysql-test/lib/*.sql $DESTDIR/mysql-test/lib/ +cp mysql-test/r/*.require $DESTDIR/mysql-test/r/ +# Need this trick, or we get "argument list too long". +ABS_DST=`pwd`/$DESTDIR +(cd mysql-test/r/ && cp *.result $ABS_DST/mysql-test/r/) +cp mysql-test/std_data/* $DESTDIR/mysql-test/std_data/ +cp mysql-test/t/*.opt $DESTDIR/mysql-test/t/ +cp mysql-test/t/*.sh $DESTDIR/mysql-test/t/ +cp mysql-test/t/*.slave-mi $DESTDIR/mysql-test/t/ +cp mysql-test/t/*.sql $DESTDIR/mysql-test/t/ +cp mysql-test/t/*.def $DESTDIR/mysql-test/t/ +(cd mysql-test/t/ && cp *.test $ABS_DST/mysql-test/t/) + +# Note that this will not copy "extra" if a soft link +if [ -d mysql-test/extra ] ; then + mkdir -p $DESTDIR/mysql-test/extra + cp -pR mysql-test/extra/* $DESTDIR/mysql-test/extra/ +fi + +# ---------------------------------------------------------------------- +# Copy what could be usable in the "scripts" directory. Currently +# only SQL files, others are bourne shell scripts or Perl scripts +# not really usable on Windows. +# +# But to be nice to the few Cygwin users we might have in 5.0 we +# continue to copy the stuff, but don't include it include it in +# the WiX install. +# ---------------------------------------------------------------------- + +mkdir -p $DESTDIR/scripts + +# Uncomment and remove the for loop in 5.1 +#cp scripts/*.sql $DESTDIR/scripts/ + +for i in `cd scripts && ls`; do \ + if echo $i | grep -q '\.sh'; then \ + cp scripts/$i $DESTDIR/scripts/`echo $i | sed -e 's/\.sh$//'`; \ + elif [ $i = Makefile.am -o $i = Makefile.in -o -e scripts/$i.sh ] ; then \ + : ; \ + else \ + cp scripts/$i $DESTDIR/scripts/$i; \ + fi; \ +done + +cp -pR sql/share $DESTDIR/ +cp -pR sql-bench $DESTDIR/ +rm -f $DESTDIR/sql-bench/*.sh $DESTDIR/sql-bench/Makefile* + +# ---------------------------------------------------------------------- +# Copy other files specified on command line DEST=SOURCE +# ---------------------------------------------------------------------- + +for arg do + dst=`echo $arg | sed 's/=.*$//'` + src=`echo $arg | sed 's/^.*=//'` + + if [ x"$dst" = x"" -o x"$src" = x"" ] ; then + echo "Invalid specification of what to copy" + usage + fi + + mkdir -p `dirname $DESTDIR/$dst` + cp -pR "$src" $DESTDIR/$dst +done + +# ---------------------------------------------------------------------- +# Finally creat the ZIP archive +# ---------------------------------------------------------------------- + +rm -f $NOINST_NAME.zip +zip -r $NOINST_NAME.zip $DESTDIR +rm -Rf $DESTDIR diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index d9333540ab8..6206ca64121 100644 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -206,7 +206,7 @@ copy_dir_files() for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def *.hpp *.yy *dsp *.dsw \ README INSTALL* LICENSE AUTHORS NEWS ChangeLog \ *.inc *.test *.result *.pem Moscow_leap des_key_file \ - *.vcproj *.sln *.dat *.000001 *.require *.opt + *.vcproj *.sln *.dat *.000001 *.require *.opt *.cnf do if [ -f $i ] then diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index c05fda745b0..5d7933e5277 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -1,4 +1,3 @@ - #!/bin/sh # Copyright (C) 2002-2003 MySQL AB # For a more info consult the file COPYRIGHT distributed with this file. diff --git a/server-tools/CMakeLists.txt b/server-tools/CMakeLists.txt new file mode 100755 index 00000000000..1983d459ce2 --- /dev/null +++ b/server-tools/CMakeLists.txt @@ -0,0 +1,18 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER) +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql + ${PROJECT_SOURCE_DIR}/extra/yassl/include) + +ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc + instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc + mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc + thread_registry.cc user_map.cc imservice.cpp windowsservice.cpp + user_management_commands.cc + ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c + ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c + ../../libmysql/errmsg.c) + +ADD_DEPENDENCIES(mysqlmanager GenError) +TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32) diff --git a/server-tools/Makefile.am b/server-tools/Makefile.am index ed316b9ac38..573bf07ccff 100644 --- a/server-tools/Makefile.am +++ b/server-tools/Makefile.am @@ -1 +1,2 @@ SUBDIRS= instance-manager +DIST_SUBDIRS= instance-manager diff --git a/server-tools/instance-manager/CMakeLists.txt b/server-tools/instance-manager/CMakeLists.txt new file mode 100755 index 00000000000..fafc3df4108 --- /dev/null +++ b/server-tools/instance-manager/CMakeLists.txt @@ -0,0 +1,17 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER) +INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql + ${PROJECT_SOURCE_DIR}/extra/yassl/include) + +ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc + instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc + mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc + thread_registry.cc user_map.cc IMService.cpp WindowsService.cpp + ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c + ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c + ../../libmysql/errmsg.c) + +ADD_DEPENDENCIES(mysqlmanager GenError) +TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32) diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am index 6b5d80a99af..b1d77506efa 100644 --- a/server-tools/instance-manager/Makefile.am +++ b/server-tools/instance-manager/Makefile.am @@ -18,7 +18,8 @@ INCLUDES= @ZLIB_INCLUDES@ -I$(top_srcdir)/include \ @openssl_includes@ -I$(top_builddir)/include DEFS= -DMYSQL_INSTANCE_MANAGER -DMYSQL_SERVER - +EXTRA_DIST = IMService.cpp IMService.h WindowsService.cpp WindowsService.h \ + CMakeLists.txt # As all autoconf variables depend from ${prefix} and being resolved only when # make is run, we can not put these defines to a header file (e.g. to # default_options.h, generated from default_options.h.in) diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 39381b457ab..2ed369ba245 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -469,37 +469,38 @@ int Instance::stop() struct timespec timeout; uint waitchild= (uint) DEFAULT_SHUTDOWN_DELAY; - if (options.shutdown_delay_val) - waitchild= options.shutdown_delay_val; + if (is_running()) + { + if (options.shutdown_delay_val) + waitchild= options.shutdown_delay_val; - kill_instance(SIGTERM); - /* sleep on condition to wait for SIGCHLD */ + kill_instance(SIGTERM); + /* sleep on condition to wait for SIGCHLD */ - timeout.tv_sec= time(NULL) + waitchild; - timeout.tv_nsec= 0; - if (pthread_mutex_lock(&LOCK_instance)) - goto err; + timeout.tv_sec= time(NULL) + waitchild; + timeout.tv_nsec= 0; + if (pthread_mutex_lock(&LOCK_instance)) + return ER_STOP_INSTANCE; - while (options.get_pid() != 0) /* while server isn't stopped */ - { - int status; + while (options.get_pid() != 0) /* while server isn't stopped */ + { + int status; - status= pthread_cond_timedwait(&COND_instance_stopped, - &LOCK_instance, - &timeout); - if (status == ETIMEDOUT || status == ETIME) - break; - } + status= pthread_cond_timedwait(&COND_instance_stopped, + &LOCK_instance, + &timeout); + if (status == ETIMEDOUT || status == ETIME) + break; + } - pthread_mutex_unlock(&LOCK_instance); + pthread_mutex_unlock(&LOCK_instance); - kill_instance(SIGKILL); + kill_instance(SIGKILL); - return 0; + return 0; + } return ER_INSTANCE_IS_NOT_STARTED; -err: - return ER_STOP_INSTANCE; } #ifdef __WIN__ diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index 67d798a1700..500b25bec03 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -88,7 +88,7 @@ Listener_thread::~Listener_thread() void Listener_thread::run() { - int n= 0; + int i, n= 0; #ifndef __WIN__ /* we use this var to check whether we are running on LinuxThreads */ @@ -117,7 +117,7 @@ void Listener_thread::run() #endif /* II. Listen sockets and spawn childs */ - for (int i= 0; i < num_sockets; i++) + for (i= 0; i < num_sockets; i++) n= max(n, sockets[i]); n++; @@ -176,7 +176,7 @@ void Listener_thread::run() log_info("Listener_thread::run(): shutdown requested, exiting..."); - for (int i= 0; i < num_sockets; i++) + for (i= 0; i < num_sockets; i++) close(sockets[i]); #ifndef __WIN__ @@ -189,7 +189,7 @@ void Listener_thread::run() err: // we have to close the ip sockets in case of error - for (int i= 0; i < num_sockets; i++) + for (i= 0; i < num_sockets; i++) close(sockets[i]); thread_registry.unregister_thread(&thread_info); diff --git a/server-tools/instance-manager/messages.cc b/server-tools/instance-manager/messages.cc index a9b00b9e01f..d2595638de0 100644 --- a/server-tools/instance-manager/messages.cc +++ b/server-tools/instance-manager/messages.cc @@ -48,8 +48,8 @@ static const char *mysqld_error_message(unsigned sql_errno) case ER_BAD_INSTANCE_NAME: return "Bad instance name. Check that the instance with such a name exists"; case ER_INSTANCE_IS_NOT_STARTED: - return "Cannot stop instance. Perhaps the instance is not started, or was started" - "manually, so IM cannot find the pidfile."; + return "Cannot stop instance. Perhaps the instance is not started, or was" + " started manually, so IM cannot find the pidfile."; case ER_INSTANCE_ALREADY_STARTED: return "The instance is already started"; case ER_CANNOT_START_INSTANCE: @@ -67,7 +67,7 @@ static const char *mysqld_error_message(unsigned sql_errno) return "Cannot open log file"; case ER_GUESS_LOGFILE: return "Cannot guess the log filename. Try specifying full log name" - "in the instance options"; + " in the instance options"; case ER_ACCESS_OPTION_FILE: return "Cannot open the option file to edit. Check permissions"; default: diff --git a/server-tools/instance-manager/portability.h b/server-tools/instance-manager/portability.h index 1a3be5705e3..23a5a5bd14c 100644 --- a/server-tools/instance-manager/portability.h +++ b/server-tools/instance-manager/portability.h @@ -1,7 +1,11 @@ #ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H #define INCLUDES_MYSQL_INSTANCE_MANAGER_PORTABILITY_H -#if defined(_SCO_DS) && !defined(SHUT_RDWR) +#if (defined(_SCO_DS) || defined(UNIXWARE_7)) && !defined(SHUT_RDWR) +/* + SHUT_* functions are defined only if + "(defined(_XOPEN_SOURCE) && _XOPEN_SOURCE_EXTENDED - 0 >= 1)" +*/ #define SHUT_RDWR 2 #endif diff --git a/sql-common/client.c b/sql-common/client.c index 45cd8befdf0..fc483e7b4c7 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -584,7 +584,7 @@ err: *****************************************************************************/ ulong -net_safe_read(MYSQL *mysql) +cli_safe_read(MYSQL *mysql) { NET *net= &mysql->net; ulong len=0; @@ -627,6 +627,16 @@ net_safe_read(MYSQL *mysql) } else set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate); + /* + Cover a protocol design error: error packet does not + contain the server status. Therefore, the client has no way + to find out whether there are more result sets of + a multiple-result-set statement pending. Luckily, in 5.0 an + error always aborts execution of a statement, wherever it is + a multi-statement or a stored procedure, so it should be + safe to unconditionally turn off the flag here. + */ + mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS; DBUG_PRINT("error",("Got error: %d/%s (%s)", net->last_errno, net->sqlstate, net->last_error)); @@ -653,7 +663,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, NET *net= &mysql->net; my_bool result= 1; init_sigpipe_variables - DBUG_ENTER("cli_advanced_command"); + DBUG_ENTER("cli_advanced_command"); /* Don't give sigpipe errors if the client doesn't want them */ set_sigpipe(mysql); @@ -663,7 +673,8 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, if (mysql_reconnect(mysql)) DBUG_RETURN(1); } - if (mysql->status != MYSQL_STATUS_READY) + if (mysql->status != MYSQL_STATUS_READY || + mysql->server_status & SERVER_MORE_RESULTS_EXISTS) { DBUG_PRINT("error",("state: %d", mysql->status)); set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); @@ -702,7 +713,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, } result=0; if (!skip_check) - result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ? + result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ? 1 : 0); end: reset_sigpipe(mysql); @@ -754,7 +765,7 @@ static void cli_flush_use_result(MYSQL *mysql) for (;;) { ulong pkt_len; - if ((pkt_len=net_safe_read(mysql)) == packet_error) + if ((pkt_len=cli_safe_read(mysql)) == packet_error) break; if (pkt_len <= 8 && mysql->net.read_pos[0] == 254) { @@ -1276,7 +1287,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, NET *net = &mysql->net; DBUG_ENTER("cli_read_rows"); - if ((pkt_len= net_safe_read(mysql)) == packet_error) + if ((pkt_len= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(0); if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), MYF(MY_WME | MY_ZEROFILL)))) @@ -1341,7 +1352,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, } } cur->data[field]=to; /* End of last field */ - if ((pkt_len=net_safe_read(mysql)) == packet_error) + if ((pkt_len=cli_safe_read(mysql)) == packet_error) { free_rows(result); DBUG_RETURN(0); @@ -1373,7 +1384,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) uchar *pos, *prev_pos, *end_pos; NET *net= &mysql->net; - if ((pkt_len=net_safe_read(mysql)) == packet_error) + if ((pkt_len=cli_safe_read(mysql)) == packet_error) return -1; if (pkt_len <= 8 && net->read_pos[0] == 254) { @@ -1503,7 +1514,6 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , mysql->options.ssl_ca= strdup_if_not_null(ca); mysql->options.ssl_capath= strdup_if_not_null(capath); mysql->options.ssl_cipher= strdup_if_not_null(cipher); - mysql->options.ssl_verify_server_cert= FALSE; /* Off by default */ #endif /* HAVE_OPENSSL */ DBUG_RETURN(0); } @@ -1650,23 +1660,23 @@ static MYSQL_RES *cli_use_result(MYSQL *mysql); static MYSQL_METHODS client_methods= { - cli_read_query_result, - cli_advanced_command, - cli_read_rows, - cli_use_result, - cli_fetch_lengths, - cli_flush_use_result + cli_read_query_result, /* read_query_result */ + cli_advanced_command, /* advanced_command */ + cli_read_rows, /* read_rows */ + cli_use_result, /* use_result */ + cli_fetch_lengths, /* fetch_lengths */ + cli_flush_use_result /* flush_use_result */ #ifndef MYSQL_SERVER - ,cli_list_fields, - cli_read_prepare_result, - cli_stmt_execute, - cli_read_binary_rows, - cli_unbuffered_fetch, - NULL, - cli_read_statistics, - cli_read_query_result, - cli_read_change_user_result, - cli_read_binary_rows + ,cli_list_fields, /* list_fields */ + cli_read_prepare_result, /* read_prepare_result */ + cli_stmt_execute, /* stmt_execute */ + cli_read_binary_rows, /* read_binary_rows */ + cli_unbuffered_fetch, /* unbuffered_fetch */ + NULL, /* free_embedded_thd */ + cli_read_statistics, /* read_statistics */ + cli_read_query_result, /* next_result */ + cli_read_change_user_result, /* read_change_user_result */ + cli_read_binary_rows /* read_rows_from_cursor */ #endif }; @@ -1748,7 +1758,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { - char buff[NAME_LEN+USERNAME_LENGTH+100]; + char buff[NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+100]; char *end,*host_info; my_socket sock; in_addr_t ip_addr; @@ -2029,7 +2039,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, Part 1: Connection established, read and parse first packet */ - if ((pkt_length=net_safe_read(mysql)) == packet_error) + if ((pkt_length=cli_safe_read(mysql)) == packet_error) goto error; /* Check if version of protocol matches current one */ @@ -2192,7 +2202,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, DBUG_PRINT("info", ("IO layer change done!")); /* Verify server cert */ - if (mysql->options.ssl_verify_server_cert && + if ((client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && ssl_verify_server_cert(mysql->net.vio, mysql->host)) { set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); @@ -2207,7 +2217,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->server_status, client_flag)); /* This needs to be changed as it's not useful with big packets */ if (user && user[0]) - strmake(end,user,USERNAME_LENGTH); /* Max user name */ + strmake(end,user,USERNAME_BYTE_LENGTH); /* Max user name */ else read_user_name((char*) end); @@ -2237,7 +2247,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* Add database if needed */ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { - end= strmake(end, db, NAME_LEN) + 1; + end= strmake(end, db, NAME_BYTE_LEN) + 1; mysql->db= my_strdup(db,MYF(MY_WME)); db= 0; } @@ -2253,7 +2263,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, OK-packet, or re-request scrambled password. */ - if ((pkt_length=net_safe_read(mysql)) == packet_error) + if ((pkt_length=cli_safe_read(mysql)) == packet_error) goto error; if (pkt_length == 1 && net->read_pos[0] == 254 && @@ -2270,7 +2280,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; } /* Read what server thinks about out new auth message report */ - if (net_safe_read(mysql) == packet_error) + if (cli_safe_read(mysql) == packet_error) goto error; } @@ -2594,7 +2604,7 @@ static my_bool cli_read_query_result(MYSQL *mysql) */ mysql = mysql->last_used_con; - if ((length = net_safe_read(mysql)) == packet_error) + if ((length = cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ #ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/ @@ -2629,7 +2639,7 @@ get_info: if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ { int error=handle_local_infile(mysql,(char*) pos); - if ((length=net_safe_read(mysql)) == packet_error || error) + if ((length= cli_safe_read(mysql)) == packet_error || error) DBUG_RETURN(1); goto get_info; /* Get info packet */ } @@ -2939,7 +2949,10 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) mysql->reconnect= *(my_bool *) arg; break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: - mysql->options.ssl_verify_server_cert= *(my_bool *) arg; + if (!arg || test(*(uint*) arg)) + mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT; + else + mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT; break; default: DBUG_RETURN(1); diff --git a/sql-common/my_time.c b/sql-common/my_time.c index c9d39260761..93bf23ed284 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -69,6 +69,7 @@ uint calc_days_in_year(uint year) Here we assume that year and month is ok ! If month is 0 we allow any date. (This only happens if we allow zero date parts in str_to_datetime()) + Disallow dates with zero year and non-zero month and/or day. RETURN 0 ok @@ -85,7 +86,8 @@ static my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date, (!(flags & TIME_INVALID_DATES) && ltime->month && ltime->day > days_in_month[ltime->month-1] && (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 || - ltime->day != 29))) + ltime->day != 29)) || + (ltime->year == 0 && (ltime->month != 0 || ltime->day != 0))) { *was_cut= 2; return TRUE; diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt new file mode 100755 index 00000000000..b01871872ce --- /dev/null +++ b/sql/CMakeLists.txt @@ -0,0 +1,114 @@ +SET(CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi") +SET(CMAKE_C_FLAGS_DEBUG + "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi") +SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_SOURCE_DIR}/bdb/build_win32 + ${CMAKE_SOURCE_DIR}/bdb/dbinc) + +SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/message.rc + ${CMAKE_SOURCE_DIR}/sql/message.h + ${CMAKE_SOURCE_DIR}/sql/sql_yacc.h + ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc + ${CMAKE_SOURCE_DIR}/include/mysql_version.h + ${CMAKE_SOURCE_DIR}/sql/lex_hash.h + ${PROJECT_SOURCE_DIR}/include/mysqld_error.h + ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h + ${PROJECT_SOURCE_DIR}/include/sql_state.h + PROPERTIES GENERATED 1) + +ADD_DEFINITIONS(-DHAVE_INNOBASE -DMYSQL_SERVER + -D_CONSOLE -DHAVE_DLOPEN) + +ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc + discover.cc ../libmysql/errmsg.c field.cc field_conv.cc + filesort.cc gstream.cc ha_blackhole.cc + ha_archive.cc ha_heap.cc ha_myisam.cc ha_myisammrg.cc + ha_innodb.cc ha_federated.cc ha_berkeley.cc ha_blackhole.cc + handler.cc hash_filo.cc hash_filo.h + hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc + item_create.cc item_func.cc item_geofunc.cc item_row.cc + item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc + item_uniq.cc key.cc log.cc lock.cc log_event.cc message.rc + message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c + ../myisammrg/myrg_rnext_same.c mysqld.cc net_serv.cc + nt_servc.cc nt_servc.h opt_range.cc opt_range.h opt_sum.cc + ../sql-common/pack.c parse_file.cc password.c procedure.cc + protocol.cc records.cc repl_failsafe.cc set_var.cc + slave.cc sp.cc sp_cache.cc sp_head.cc sp_pcontext.cc + sp_rcontext.cc spatial.cc sql_acl.cc sql_analyse.cc sql_base.cc + sql_cache.cc sql_class.cc sql_client.cc sql_crypt.cc sql_crypt.h + sql_cursor.cc sql_db.cc sql_delete.cc sql_derived.cc sql_do.cc + sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc + sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc + sql_prepare.cc sql_rename.cc + sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc + sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc + sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc + time.cc tztime.cc uniques.cc unireg.cc + ../sql-common/my_user.c + sql_locale.cc + ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc + ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h + ${PROJECT_SOURCE_DIR}/include/mysqld_error.h + ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h + ${PROJECT_SOURCE_DIR}/include/sql_state.h + ${PROJECT_SOURCE_DIR}/include/mysql_version.h + ${PROJECT_SOURCE_DIR}/sql/lex_hash.h) + +TARGET_LINK_LIBRARIES(mysqld heap myisam myisammrg mysys yassl zlib dbug yassl + taocrypt strings vio regex wsock32) + +IF(WITH_EXAMPLE_STORAGE_ENGINE) + TARGET_LINK_LIBRARIES(mysqld example) +ENDIF(WITH_EXAMPLE_STORAGE_ENGINE) + +IF(WITH_INNOBASE_STORAGE_ENGINE) + TARGET_LINK_LIBRARIES(mysqld innobase) +ENDIF(WITH_INNOBASE_STORAGE_ENGINE) + +IF(WITH_BERKELEY_STORAGE_ENGINE) + TARGET_LINK_LIBRARIES(mysqld bdb) +ENDIF(WITH_BERKELEY_STORAGE_ENGINE) + + +ADD_DEPENDENCIES(mysqld GenError) + +# Sql Parser custom command +ADD_CUSTOM_COMMAND( + SOURCE ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy + OUTPUT ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc + COMMAND bison.exe ARGS -y -p MYSQL --defines=sql_yacc.h + --output=sql_yacc.cc sql_yacc.yy + DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy) + +ADD_CUSTOM_COMMAND( + OUTPUT ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h + COMMAND echo + DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc +) + +# Windows message file +ADD_CUSTOM_COMMAND( + SOURCE ${PROJECT_SOURCE_DIR}/sql/message.mc + OUTPUT message.rc message.h + COMMAND mc ARGS ${PROJECT_SOURCE_DIR}/sql/message.mc + DEPENDS ${PROJECT_SOURCE_DIR}/sql/message.mc) + +# Gen_lex_hash +ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc) +TARGET_LINK_LIBRARIES(gen_lex_hash dbug mysqlclient wsock32) +GET_TARGET_PROPERTY(GEN_LEX_HASH_EXE gen_lex_hash LOCATION) +ADD_CUSTOM_COMMAND( + OUTPUT ${PROJECT_SOURCE_DIR}/sql/lex_hash.h + COMMAND ${GEN_LEX_HASH_EXE} ARGS > lex_hash.h + DEPENDS ${GEN_LEX_HASH_EXE} +) + +ADD_DEPENDENCIES(mysqld gen_lex_hash) diff --git a/sql/Makefile.am b/sql/Makefile.am index 8428d6401b5..98c8fe784eb 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -116,9 +116,11 @@ DEFS = -DMYSQL_SERVER \ @DEFS@ BUILT_SOURCES = sql_yacc.cc sql_yacc.h lex_hash.h -EXTRA_DIST = $(BUILT_SOURCES) -DISTCLEANFILES = lex_hash.h -AM_YFLAGS = -d +EXTRA_DIST = $(BUILT_SOURCES) nt_servc.cc nt_servc.h \ + message.mc examples/CMakeLists.txt CMakeLists.txt +DISTCLEANFILES = lex_hash.h sql_yacc.output + +AM_YFLAGS = -d --debug --verbose mysql_tzinfo_to_sql.cc: rm -f mysql_tzinfo_to_sql.cc diff --git a/sql/examples/CMakeLists.txt b/sql/examples/CMakeLists.txt new file mode 100755 index 00000000000..d3cc430ef40 --- /dev/null +++ b/sql/examples/CMakeLists.txt @@ -0,0 +1,11 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/regex) + +IF(WITH_EXAMPLE_STORAGE_ENGINE) +ADD_LIBRARY(example ha_example.cc) +ADD_DEPENDENCIES(example GenError) +ENDIF(WITH_EXAMPLE_STORAGE_ENGINE) diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 8ae82f97d0b..f727cefc6d0 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -101,13 +101,34 @@ static byte* tina_get_key(TINA_SHARE *share,uint *length, return (byte*) share->table_name; } + +int free_mmap(TINA_SHARE *share) +{ + DBUG_ENTER("ha_tina::free_mmap"); + if (share->mapped_file) + { + /* + Invalidate the mapped in pages. Some operating systems (eg OpenBSD) + would reuse already cached pages even if the file has been altered + using fd based I/O. This may be optimized by perhaps only invalidating + the last page but optimization of deprecated code is not important. + */ + msync(share->mapped_file, 0, MS_INVALIDATE); + if (munmap(share->mapped_file, share->file_stat.st_size)) + DBUG_RETURN(1); + } + share->mapped_file= NULL; + DBUG_RETURN(0); +} + /* Reloads the mmap file. */ int get_mmap(TINA_SHARE *share, int write) { DBUG_ENTER("ha_tina::get_mmap"); - if (share->mapped_file && munmap(share->mapped_file, share->file_stat.st_size)) + + if (free_mmap(share)) DBUG_RETURN(1); if (my_fstat(share->data_file, &share->file_stat, MYF(MY_WME)) == -1) @@ -184,16 +205,18 @@ static TINA_SHARE *get_share(const char *table_name, TABLE *table) share->table_name_length=length; share->table_name=tmp_name; strmov(share->table_name,table_name); - fn_format(data_file_name, table_name, "", ".CSV",MY_REPLACE_EXT|MY_UNPACK_FILENAME); + fn_format(data_file_name, table_name, "", ".CSV", + MY_REPLACE_EXT | MY_UNPACK_FILENAME); + + if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND, + MYF(0))) == -1) + goto error; + if (my_hash_insert(&tina_open_tables, (byte*) share)) goto error; thr_lock_init(&share->lock); pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); - if ((share->data_file= my_open(data_file_name, O_RDWR|O_APPEND, - MYF(0))) == -1) - goto error2; - /* We only use share->data_file for writing, so we scan to the end to append */ if (my_seek(share->data_file, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR) goto error2; @@ -212,6 +235,7 @@ error3: error2: thr_lock_delete(&share->lock); pthread_mutex_destroy(&share->mutex); + hash_delete(&tina_open_tables, (byte*) share); error: pthread_mutex_unlock(&tina_mutex); my_free((gptr) share, MYF(0)); @@ -230,8 +254,7 @@ static int free_share(TINA_SHARE *share) int result_code= 0; if (!--share->use_count){ /* Drop the mapped file */ - if (share->mapped_file) - munmap(share->mapped_file, share->file_stat.st_size); + free_mmap(share); result_code= my_close(share->data_file,MYF(0)); hash_delete(&tina_open_tables, (byte*) share); thr_lock_delete(&share->lock); @@ -493,6 +516,13 @@ int ha_tina::write_row(byte * buf) size= encode_quote(buf); + /* + we are going to alter the file so we must invalidate the in memory pages + otherwise we risk a race between the in memory pages and the disk pages. + */ + if (free_mmap(share)) + DBUG_RETURN(-1); + if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP))) DBUG_RETURN(-1); @@ -534,8 +564,26 @@ int ha_tina::update_row(const byte * old_data, byte * new_data) if (chain_append()) DBUG_RETURN(-1); + /* + we are going to alter the file so we must invalidate the in memory pages + otherwise we risk a race between the in memory pages and the disk pages. + */ + if (free_mmap(share)) + DBUG_RETURN(-1); + if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP))) DBUG_RETURN(-1); + + /* + Ok, this is means that we will be doing potentially bad things + during a bulk update on some OS'es. Ideally, we should extend the length + of the file, redo the mmap and then write all the updated rows. Upon + finishing the bulk update, truncate the file length to the final length. + Since this code is all being deprecated, not point now to optimize. + */ + if (get_mmap(share, 0) > 0) + DBUG_RETURN(-1); + DBUG_RETURN(0); } @@ -812,15 +860,14 @@ int ha_tina::rnd_end() length= length - (size_t)(ptr->end - ptr->begin); } - /* Truncate the file to the new size */ - if (my_chsize(share->data_file, length, 0, MYF(MY_WME))) + /* Invalidate all cached mmap pages */ + if (free_mmap(share)) DBUG_RETURN(-1); - if (munmap(share->mapped_file, length)) + /* Truncate the file to the new size */ + if (my_chsize(share->data_file, length, 0, MYF(MY_WME))) DBUG_RETURN(-1); - /* We set it to null so that get_mmap() won't try to unmap it */ - share->mapped_file= NULL; if (get_mmap(share, 0) > 0) DBUG_RETURN(-1); } @@ -838,6 +885,10 @@ int ha_tina::delete_all_rows() if (!records_is_known) return (my_errno=HA_ERR_WRONG_COMMAND); + /* Invalidate all cached mmap pages */ + if (free_mmap(share)) + DBUG_RETURN(-1); + int rc= my_chsize(share->data_file, 0, 0, MYF(MY_WME)); if (get_mmap(share, 0) > 0) diff --git a/sql/field.cc b/sql/field.cc index 98de224f900..4860f6ea3da 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4387,6 +4387,24 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, } +Field_timestamp::Field_timestamp(bool maybe_null_arg, + const char *field_name_arg, + struct st_table *table_arg, CHARSET_INFO *cs) + :Field_str((char*) 0, 19, maybe_null_arg ? (uchar*) "": 0, 0, + NONE, field_name_arg, table_arg, cs) +{ + /* For 4.0 MYD and 4.0 InnoDB compatibility */ + flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; + if (table && !table->timestamp_field && + unireg_check != NONE) + { + /* This timestamp has auto-update */ + table->timestamp_field= this; + flags|=TIMESTAMP_FLAG; + } +} + + /* Get auto-set type for TIMESTAMP field. @@ -6136,15 +6154,26 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table, Field *new_field; if (type() != MYSQL_TYPE_VAR_STRING || keep_type) - return Field::new_field(root, new_table, keep_type); + new_field= Field::new_field(root, new_table, keep_type); + else + { - /* - Old VARCHAR field which should be modified to a VARCHAR on copy - This is done to ensure that ALTER TABLE will convert old VARCHAR fields - to now VARCHAR fields. - */ - return new Field_varstring(field_length, maybe_null(), - field_name, new_table, charset()); + /* + Old VARCHAR field which should be modified to a VARCHAR on copy + This is done to ensure that ALTER TABLE will convert old VARCHAR fields + to now VARCHAR fields. + */ + new_field= new Field_varstring(field_length, maybe_null(), + field_name, new_table, charset()); + /* + Normally orig_table is different from table only if field was created + via ::new_field. Here we alter the type of field, so ::new_field is + not applicable. But we still need to preserve the original field + metadata for the client-server protocol. + */ + new_field->orig_table= orig_table; + } + return new_field; } /**************************************************************************** @@ -6394,6 +6423,11 @@ void Field_varstring::sql_type(String &res) const } +uint32 Field_varstring::data_length(const char *from) +{ + return length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr); +} + /* Functions to create a packed row. Here the number of length bytes are depending on the given max_length @@ -8265,7 +8299,8 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, comment= *fld_comment; /* - Set flag if this field doesn't have a default value + Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and + it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP. */ if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) && (fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP) @@ -8342,12 +8377,28 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, /* Allow empty as default value. */ String str,*res; res= fld_default_value->val_str(&str); - if (res->length()) + /* + A default other than '' is always an error, and any non-NULL + specified default is an error in strict mode. + */ + if (res->length() || (thd->variables.sql_mode & + (MODE_STRICT_TRANS_TABLES | + MODE_STRICT_ALL_TABLES))) { my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name); /* purecov: inspected */ DBUG_RETURN(TRUE); } + else + { + /* + Otherwise a default of '' is just a warning. + */ + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_BLOB_CANT_HAVE_DEFAULT, + ER(ER_BLOB_CANT_HAVE_DEFAULT), + fld_name); + } def= 0; } flags|= BLOB_FLAG; diff --git a/sql/field.h b/sql/field.h index 09638b9a979..65e747e9d2f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -144,6 +144,11 @@ public: table, which is located on disk). */ virtual uint32 pack_length_in_rec() const { return pack_length(); } + + /* + data_length() return the "real size" of the data in memory. + */ + virtual uint32 data_length(const char *from) { return pack_length(); } virtual uint32 sort_length() const { return pack_length(); } virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset_fields() {} @@ -780,6 +785,8 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg, CHARSET_INFO *cs); + Field_timestamp(bool maybe_null_arg, const char *field_name_arg, + struct st_table *table_arg, CHARSET_INFO *cs); enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } @@ -1100,6 +1107,7 @@ public: int key_cmp(const byte *str, uint length); uint packed_col_length(const char *to, uint length); uint max_packed_col_length(uint max_length); + uint32 data_length(const char *from); uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } bool has_charset(void) const @@ -1128,6 +1136,21 @@ public: { flags|= BLOB_FLAG; } + Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, + struct st_table *table_arg, CHARSET_INFO *cs, bool set_packlength) + :Field_longstr((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0, + NONE, field_name_arg, table_arg, cs) + { + flags|= BLOB_FLAG; + packlength= 4; + if (set_packlength) + { + uint32 char_length= len_arg/cs->mbmaxlen; + packlength= char_length <= 255 ? 1 : + char_length <= 65535 ? 2 : + char_length <= 16777215 ? 3 : 4; + } + } enum_field_types type() const { return FIELD_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index e59986092e4..5a8bd48d699 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -450,6 +450,7 @@ int main(int argc,char **argv) and you are welcome to modify and redistribute it under the GPL license\n\ \n*/\n\n"); + /* Broken up to indicate that it's not advice to you, gentle reader. */ printf("/* Do " "not " "edit " "this " "file! This is generated by " "gen_lex_hash.cc\nthat seeks for a perfect hash function */\n\n"); printf("#include \"lex.h\"\n\n"); @@ -475,8 +476,10 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\ if (len == 0) {\n\ DBUG_PRINT(\"warning\", (\"get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake.\"));\ return(NULL);\n\ - }\ -\n\ + }\n" +); + + printf("\ if (function){\n\ if (len>sql_functions_max_len) return 0;\n\ hash_map= sql_functions_map;\n\ @@ -507,7 +510,10 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\ cur_struct= uint4korr(hash_map+\n\ (((uint16)cur_struct + cur_char - first_char)*4));\n\ cur_str++;\n\ - }\n\ + }\n" +); + + printf("\ }else{\n\ if (len>symbols_max_len) return 0;\n\ hash_map= symbols_map;\n\ diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc index 3885defb4d5..bb94a99e700 100644 --- a/sql/ha_archive.cc +++ b/sql/ha_archive.cc @@ -614,7 +614,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, error= my_errno; goto error; } - if ((archive= gzdopen(create_file, "wb")) == NULL) + if ((archive= gzdopen(dup(create_file), "wb")) == NULL) { error= errno; goto error2; @@ -710,6 +710,28 @@ int ha_archive::write_row(byte *buf) if (init_archive_writer()) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); + /* + Varchar structures are constant in size but are not cleaned up request + to request. The following sets all unused space to null to improve + compression. + */ + for (Field **field=table->field ; *field ; field++) + { + DBUG_PRINT("archive",("Pack is %d\n", (*field)->pack_length())); + DBUG_PRINT("archive",("MyPack is %d\n", (*field)->data_length((char*) buf + (*field)->offset()))); + if ((*field)->real_type() == MYSQL_TYPE_VARCHAR) + { + uint actual_length= (*field)->data_length((char*) buf + (*field)->offset()); + uint offset= (*field)->offset() + actual_length + + (actual_length > 255 ? 2 : 1); + DBUG_PRINT("archive",("Offset is %d -> %d\n", actual_length, offset)); + /* + if ((*field)->pack_length() + (*field)->offset() != offset) + bzero(buf + offset, (size_t)((*field)->pack_length() + (actual_length > 255 ? 2 : 1) - (*field)->data_length)); + */ + } + } + share->rows_recorded++; rc= real_write_row(buf, share->archive_write); pthread_mutex_unlock(&share->mutex); diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 2267c2b5d79..7919519cdce 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -332,6 +332,7 @@ */ + #include "mysql_priv.h" #ifdef USE_PRAGMA_IMPLEMENTATION #pragma implementation // gcc: Class implementation diff --git a/sql/ha_federated.h b/sql/ha_federated.h index 85474d142a3..61f5af686a3 100644 --- a/sql/ha_federated.h +++ b/sql/ha_federated.h @@ -196,7 +196,9 @@ public: /* fix server to be able to get remote server table flags */ return (HA_NOT_EXACT_COUNT | HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_REC_NOT_IN_SEQ | - HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS| HA_NO_PREFIX_CHAR_KEYS); + HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS| HA_NO_PREFIX_CHAR_KEYS | + HA_NULL_IN_KEY + ); } /* This is a bitmap of flags that says how the storage engine diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 472506f9903..c56be6376d0 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2190,8 +2190,7 @@ ha_innobase::open( "have forgotten\nto delete the corresponding " ".frm files of InnoDB tables, or you\n" "have moved .frm files to another database?\n" - "Look from section 15.1 of " - "http://www.innodb.com/ibman.html\n" + "See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "how you can resolve the problem.\n", norm_name); free_share(share); @@ -2208,8 +2207,7 @@ ha_innobase::open( "Have you deleted the .ibd file from the " "database directory under\nthe MySQL datadir, " "or have you used DISCARD TABLESPACE?\n" - "Look from section 15.1 of " - "http://www.innodb.com/ibman.html\n" + "See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "how you can resolve the problem.\n", norm_name); free_share(share); @@ -5384,13 +5382,14 @@ ha_innobase::info( for (i = 0; i < table->s->keys; i++) { if (index == NULL) { ut_print_timestamp(stderr); - sql_print_error("Table %s contains less " + sql_print_error("Table %s contains fewer " "indexes inside InnoDB than " "are defined in the MySQL " ".frm file. Have you mixed up " ".frm files from different " - "installations? See section " - "15.1 at http://www.innodb.com/ibman.html", + "installations? See " +"http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", + ib_table->name); break; } @@ -5399,17 +5398,11 @@ ha_innobase::info( if (j + 1 > index->n_uniq) { ut_print_timestamp(stderr); - sql_print_error("Index %s of %s has " - "%lu columns unique " - "inside InnoDB, but " - "MySQL is asking " - "statistics for %lu " - "columns. Have you " - "mixed up .frm files " - "from different " - "installations? See " - "section 15.1 at " - "http://www.innodb.com/ibman.html", + sql_print_error( +"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking " +"statistics for %lu columns. Have you mixed up .frm files from different " +"installations? " +"See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n", index->name, ib_table->name, (unsigned long) @@ -6207,7 +6200,7 @@ ha_innobase::transactional_table_lock( "table %s does not exist.\n" "Have you deleted the .ibd file from the database directory under\n" "the MySQL datadir?" -"Look from section 15.1 of http://www.innodb.com/ibman.html\n" +"See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n" "how you can resolve the problem.\n", prebuilt->table->name); DBUG_RETURN(HA_ERR_CRASHED); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1af677fa754..9c4a2c20ca0 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -35,6 +35,7 @@ // options from from mysqld.cc extern my_bool opt_ndb_optimized_node_selection; extern const char *opt_ndbcluster_connectstring; +extern ulong opt_ndb_cache_check_time; // Default value for parallelism static const int parallelism= 0; @@ -228,13 +229,15 @@ static int ndb_to_mysql_error(const NdbError *err) inline -int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans) +int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans, + bool force_release) { #ifdef NOT_USED int m_batch_execute= 0; if (m_batch_execute) return 0; #endif + h->release_completed_operations(trans, force_release); return trans->execute(NdbTransaction::NoCommit, NdbTransaction::AbortOnError, h->m_force_send); @@ -267,13 +270,15 @@ int execute_commit(THD *thd, NdbTransaction *trans) } inline -int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans) +int execute_no_commit_ie(ha_ndbcluster *h, NdbTransaction *trans, + bool force_release) { #ifdef NOT_USED int m_batch_execute= 0; if (m_batch_execute) return 0; #endif + h->release_completed_operations(trans, force_release); return trans->execute(NdbTransaction::NoCommit, NdbTransaction::AO_IgnoreError, h->m_force_send); @@ -290,6 +295,7 @@ Thd_ndb::Thd_ndb() all= NULL; stmt= NULL; error= 0; + query_state&= NDB_QUERY_NORMAL; } Thd_ndb::~Thd_ndb() @@ -1443,7 +1449,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) if ((res= define_read_attrs(buf, op))) DBUG_RETURN(res); - if (execute_no_commit_ie(this,trans) != 0) + if (execute_no_commit_ie(this,trans,false) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1490,7 +1496,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) ERR_RETURN(trans->getNdbError()); } } - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1630,7 +1636,7 @@ int ha_ndbcluster::peek_indexed_rows(const byte *record) } last= trans->getLastDefinedOperation(); if (first) - res= execute_no_commit_ie(this,trans); + res= execute_no_commit_ie(this,trans,false); else { // Table has no keys @@ -1679,7 +1685,7 @@ int ha_ndbcluster::unique_index_read(const byte *key, if ((res= define_read_attrs(buf, op))) DBUG_RETURN(res); - if (execute_no_commit_ie(this,trans) != 0) + if (execute_no_commit_ie(this,trans,false) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -1727,7 +1733,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor) */ if (m_ops_pending && m_blobs_pending) { - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(ndb_err(trans)); m_ops_pending= 0; m_blobs_pending= FALSE; @@ -1759,7 +1765,7 @@ inline int ha_ndbcluster::fetch_next(NdbScanOperation* cursor) { if (m_transaction_on) { - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(-1); } else @@ -2063,7 +2069,7 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, DBUG_RETURN(res); } - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(ndb_err(trans)); DBUG_RETURN(next_result(buf)); @@ -2096,7 +2102,7 @@ int ha_ndbcluster::full_table_scan(byte *buf) if ((res= define_read_attrs(buf, op))) DBUG_RETURN(res); - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) DBUG_RETURN(ndb_err(trans)); DBUG_PRINT("exit", ("Scan started successfully")); DBUG_RETURN(next_result(buf)); @@ -2228,7 +2234,7 @@ int ha_ndbcluster::write_row(byte *record) m_bulk_insert_not_flushed= FALSE; if (m_transaction_on) { - if (execute_no_commit(this,trans) != 0) + if (execute_no_commit(this,trans,false) != 0) { m_skip_auto_increment= TRUE; no_uncommitted_rows_execute_failure(); @@ -2428,7 +2434,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) } // Execute update operation - if (!cursor && execute_no_commit(this,trans) != 0) { + if (!cursor && execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2499,7 +2505,7 @@ int ha_ndbcluster::delete_row(const byte *record) } // Execute delete operation - if (execute_no_commit(this,trans) != 0) { + if (execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2928,6 +2934,26 @@ int ha_ndbcluster::close_scan() NdbScanOperation *cursor= m_active_cursor ? m_active_cursor : m_multi_cursor; + if (m_lock_tuple) + { + /* + Lock level m_lock.type either TL_WRITE_ALLOW_WRITE + (SELECT FOR UPDATE) or TL_READ_WITH_SHARED_LOCKS (SELECT + LOCK WITH SHARE MODE) and row was not explictly unlocked + with unlock_row() call + */ + NdbOperation *op; + // Lock row + DBUG_PRINT("info", ("Keeping lock on scanned row")); + + if (!(op= cursor->lockCurrentTuple())) + { + m_lock_tuple= false; + ERR_RETURN(trans->getNdbError()); + } + m_ops_pending++; + } + m_lock_tuple= false; if (m_ops_pending) { /* @@ -2935,7 +2961,7 @@ int ha_ndbcluster::close_scan() deleteing/updating transaction before closing the scan */ DBUG_PRINT("info", ("ops_pending: %d", m_ops_pending)); - if (execute_no_commit(this,trans) != 0) { + if (execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -3345,7 +3371,7 @@ int ha_ndbcluster::end_bulk_insert() m_bulk_insert_not_flushed= FALSE; if (m_transaction_on) { - if (execute_no_commit(this, trans) != 0) + if (execute_no_commit(this, trans,false) != 0) { no_uncommitted_rows_execute_failure(); my_errno= error= ndb_err(trans); @@ -3500,7 +3526,14 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) if (lock_type != F_UNLCK) { DBUG_PRINT("info", ("lock_type != F_UNLCK")); - if (!thd->transaction.on) + if (thd->lex->sql_command == SQLCOM_LOAD) + { + m_transaction_on= FALSE; + /* Would be simpler if has_transactions() didn't always say "yes" */ + thd->options|= OPTION_STATUS_NO_TRANS_UPDATE; + thd->no_trans_update= TRUE; + } + else if (!thd->transaction.on) m_transaction_on= FALSE; else m_transaction_on= thd->variables.ndb_use_transactions; @@ -3518,6 +3551,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->stmt= trans; + thd_ndb->query_state&= NDB_QUERY_NORMAL; trans_register_ha(thd, FALSE, &ndbcluster_hton); } else @@ -3533,6 +3567,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type) ERR_RETURN(ndb->getNdbError()); no_uncommitted_rows_reset(thd); thd_ndb->all= trans; + thd_ndb->query_state&= NDB_QUERY_NORMAL; trans_register_ha(thd, TRUE, &ndbcluster_hton); /* @@ -3739,6 +3774,7 @@ int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type) thd_ndb->stmt= trans; trans_register_ha(thd, FALSE, &ndbcluster_hton); } + thd_ndb->query_state&= NDB_QUERY_NORMAL; m_active_trans= trans; // Start of statement @@ -4147,10 +4183,15 @@ static void ndb_set_fragmentation(NDBTAB &tab, TABLE *form, uint pk_length) acc_row_size+= 4 + /*safety margin*/ 4; #endif ulonglong acc_fragment_size= 512*1024*1024; + /* + * if not --with-big-tables then max_rows is ulong + * the warning in this case is misleading though + */ + ulonglong big_max_rows = (ulonglong)max_rows; #if MYSQL_VERSION_ID >= 50100 - no_fragments= (max_rows*acc_row_size)/acc_fragment_size+1; + no_fragments= (big_max_rows*acc_row_size)/acc_fragment_size+1; #else - no_fragments= ((max_rows*acc_row_size)/acc_fragment_size+1 + no_fragments= ((big_max_rows*acc_row_size)/acc_fragment_size+1 +1/*correct rounding*/)/2; #endif } @@ -5210,6 +5251,7 @@ bool ndbcluster_init() pthread_cond_init(&COND_ndb_util_thread, NULL); + ndb_cache_check_time = opt_ndb_cache_check_time; // Create utility thread pthread_t tmp; if (pthread_create(&tmp, &connection_attrib, ndb_util_thread_func, 0)) @@ -5986,6 +6028,30 @@ int ha_ndbcluster::write_ndb_file() DBUG_RETURN(error); } +void +ha_ndbcluster::release_completed_operations(NdbTransaction *trans, + bool force_release) +{ + if (trans->hasBlobOperation()) + { + /* We are reading/writing BLOB fields, + releasing operation records is unsafe + */ + return; + } + if (!force_release) + { + if (get_thd_ndb(current_thd)->query_state & NDB_QUERY_MULTI_READ_RANGE) + { + /* We are batching reads and have not consumed all fetched + rows yet, releasing operation records is unsafe + */ + return; + } + } + trans->releaseCompletedOperations(); +} + int ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, KEY_MULTI_RANGE *ranges, @@ -6000,6 +6066,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, NDB_INDEX_TYPE index_type= get_index_type(active_index); ulong reclength= table->s->reclength; NdbOperation* op; + Thd_ndb *thd_ndb= get_thd_ndb(current_thd); if (uses_blob_value(m_retrieve_all_fields)) { @@ -6013,7 +6080,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, sorted, buffer)); } - + thd_ndb->query_state|= NDB_QUERY_MULTI_READ_RANGE; m_disable_multi_read= FALSE; /** @@ -6160,7 +6227,7 @@ ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p, */ m_current_multi_operation= lastOp ? lastOp->next() : m_active_trans->getFirstDefinedOperation(); - if (!(res= execute_no_commit_ie(this, m_active_trans))) + if (!(res= execute_no_commit_ie(this, m_active_trans, true))) { m_multi_range_defined= multi_range_curr; multi_range_curr= ranges; diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 01950c2b00f..cfb12981b98 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -435,6 +435,11 @@ class Ndb_cond_traverse_context Ndb_rewrite_context *rewrite_stack; }; +typedef enum ndb_query_state_bits { + NDB_QUERY_NORMAL = 0, + NDB_QUERY_MULTI_READ_RANGE = 1 +} NDB_QUERY_STATE_BITS; + /* Place holder for ha_ndbcluster thread specific data */ @@ -451,6 +456,7 @@ class Thd_ndb NdbTransaction *stmt; int error; List<NDB_SHARE> changed_tables; + uint query_state; }; class ha_ndbcluster: public handler @@ -672,8 +678,8 @@ private: NdbScanOperation* op); friend int execute_commit(ha_ndbcluster*, NdbTransaction*); - friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*); - friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*); + friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool); + friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool); NdbTransaction *m_active_trans; NdbScanOperation *m_active_cursor; @@ -716,6 +722,8 @@ private: bool m_force_send; ha_rows m_autoincrement_prefetch; bool m_transaction_on; + void release_completed_operations(NdbTransaction*, bool); + Ndb_cond_stack *m_cond_stack; bool m_disable_multi_read; byte *m_multi_range_result_ptr; diff --git a/sql/item.cc b/sql/item.cc index ad8b79182d4..34e5e2da165 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -305,6 +305,7 @@ Item::Item(): maybe_null=null_value=with_sum_func=unsigned_flag=0; decimals= 0; max_length= 0; with_subselect= 0; + cmp_context= (Item_result)-1; /* Put item in free list so that we can free all items at end */ THD *thd= current_thd; @@ -343,7 +344,8 @@ Item::Item(THD *thd, Item *item): unsigned_flag(item->unsigned_flag), with_sum_func(item->with_sum_func), fixed(item->fixed), - collation(item->collation) + collation(item->collation), + cmp_context(item->cmp_context) { next= thd->free_list; // Put in free list thd->free_list= this; @@ -420,6 +422,49 @@ void Item::rename(char *new_name) } +/* + Traverse item tree possibly transforming it (replacing items). + + SYNOPSIS + Item::transform() + transformer functor that performs transformation of a subtree + arg opaque argument passed to the functor + + DESCRIPTION + This function is designed to ease transformation of Item trees. + + Re-execution note: every such transformation is registered for + rollback by THD::change_item_tree() and is rolled back at the end + of execution by THD::rollback_item_tree_changes(). + + Therefore: + + - this function can not be used at prepared statement prepare + (in particular, in fix_fields!), as only permanent + transformation of Item trees are allowed at prepare. + + - the transformer function shall allocate new Items in execution + memory root (thd->mem_root) and not anywhere else: allocated + items will be gone in the end of execution. + + If you don't need to transform an item tree, but only traverse + it, please use Item::walk() instead. + + + RETURN VALUE + Returns pointer to the new subtree root. THD::change_item_tree() + should be called for it if transformation took place, i.e. if a + pointer to newly allocated item is returned. +*/ + +Item* Item::transform(Item_transformer transformer, byte *arg) +{ + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + + return (this->*transformer)(arg); +} + + Item_ident::Item_ident(Name_resolution_context *context_arg, const char *db_name_arg,const char *table_name_arg, const char *field_name_arg) @@ -1424,7 +1469,8 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, In case we're in statement prepare, create conversion item in its memory: it will be reused on each execute. */ - arena= thd->activate_stmt_arena_if_needed(&backup); + arena= thd->is_stmt_prepare() ? thd->activate_stmt_arena_if_needed(&backup) + : NULL; for (i= 0, arg= args; i < nargs; i++, arg+= item_sep) { @@ -1459,7 +1505,7 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, been created in prepare. In this case register the change for rollback. */ - if (arena && arena->is_conventional()) + if (arena) *arg= conv; else thd->change_item_tree(arg, conv); @@ -3776,7 +3822,19 @@ Item *Item_field::equal_fields_propagator(byte *arg) Item *item= 0; if (item_equal) item= item_equal->get_const(); - if (!item) + /* + Disable const propagation for items used in different comparison contexts. + This must be done because, for example, Item_hex_string->val_int() is not + the same as (Item_hex_string->val_str() in BINARY column)->val_int(). + We cannot simply disable the replacement in a particular context ( + e.g. <bin_col> = <int_col> AND <bin_col> = <hex_string>) since + Items don't know the context they are in and there are functions like + IF (<hex_string>, 'yes', 'no'). + The same problem occurs when comparing a DATE/TIME field with a + DATE/TIME represented as an int and as a string. + */ + if (!item || + (cmp_context != (Item_result)-1 && item->cmp_context != cmp_context)) item= this; return item; } @@ -3787,11 +3845,11 @@ Item *Item_field::equal_fields_propagator(byte *arg) See comments in Arg_comparator::set_compare_func() for details */ -Item *Item_field::set_no_const_sub(byte *arg) +bool Item_field::set_no_const_sub(byte *arg) { if (field->charset() != &my_charset_bin) no_const_subst=1; - return this; + return FALSE; } @@ -3903,7 +3961,9 @@ Field *Item::make_string_field(TABLE *table) if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB) return new Field_blob(max_length, maybe_null, name, table, collation.collation); - if (max_length > 0) + /* Item_type_holder holds the exact type, do not change it */ + if (max_length > 0 && + (type() != Item::TYPE_HOLDER || field_type() != MYSQL_TYPE_STRING)) return new Field_varstring(max_length, maybe_null, name, table, collation.collation); return new Field_string(max_length, maybe_null, name, table, @@ -3967,6 +4027,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) case MYSQL_TYPE_TIME: return new Field_time(maybe_null, name, table, &my_charset_bin); case MYSQL_TYPE_TIMESTAMP: + return new Field_timestamp(maybe_null, name, table, &my_charset_bin); case MYSQL_TYPE_DATETIME: return new Field_datetime(maybe_null, name, table, &my_charset_bin); case MYSQL_TYPE_YEAR: @@ -3990,7 +4051,11 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table) case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_GEOMETRY: - return new Field_blob(max_length, maybe_null, name, table, + if (this->type() == Item::TYPE_HOLDER) + return new Field_blob(max_length, maybe_null, name, table, + collation.collation, 1); + else + return new Field_blob(max_length, maybe_null, name, table, collation.collation); break; // Blob handled outside of case } @@ -5286,6 +5351,31 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions) } +/* + This method like the walk method traverses the item tree, but at the + same time it can replace some nodes in the tree +*/ + +Item *Item_default_value::transform(Item_transformer transformer, byte *args) +{ + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + + Item *new_item= arg->transform(transformer, args); + if (!new_item) + return 0; + + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ + if (arg != new_item) + current_thd->change_item_tree(&arg, new_item); + return (this->*transformer)(args); +} + + bool Item_insert_value::eq(const Item *item, bool binary_cmp) const { return item->type() == INSERT_VALUE_ITEM && @@ -6053,14 +6143,13 @@ bool Item_type_holder::join_types(THD *thd, Item *item) max_length= my_decimal_precision_to_length(precision, decimals, unsigned_flag); } - else - max_length= max(max_length, display_length(item)); - + switch (Field::result_merge_type(fld_type)) { case STRING_RESULT: { const char *old_cs, *old_derivation; + uint32 old_max_chars= max_length / collation.collation->mbmaxlen; old_cs= collation.collation->name; old_derivation= collation.derivation_name(); if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV)) @@ -6072,6 +6161,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item) "UNION"); DBUG_RETURN(TRUE); } + /* + To figure out max_length, we have to take into account possible + expansion of the size of the values because of character set + conversions. + */ + max_length= max(old_max_chars * collation.collation->mbmaxlen, + display_length(item) / item->collation.collation->mbmaxlen * + collation.collation->mbmaxlen); break; } case REAL_RESULT: @@ -6090,7 +6187,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item) max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7; break; } - default:; + default: + max_length= max(max_length, display_length(item)); }; maybe_null|= item->maybe_null; get_full_info(item); @@ -6151,7 +6249,7 @@ uint32 Item_type_holder::display_length(Item *item) case MYSQL_TYPE_DOUBLE: return 53; case MYSQL_TYPE_NULL: - return 4; + return 0; case MYSQL_TYPE_LONGLONG: return 20; case MYSQL_TYPE_INT24: diff --git a/sql/item.h b/sql/item.h index 0f49145082f..58a3bfd0d75 100644 --- a/sql/item.h +++ b/sql/item.h @@ -465,7 +465,7 @@ public: my_bool with_subselect; /* If this item is a subselect or some of its arguments is or contains a subselect */ - + Item_result cmp_context; /* Comparison context */ // alloc & destruct is done as start of select using sql_alloc Item(); /* @@ -734,10 +734,7 @@ public: return (this->*processor)(arg); } - virtual Item* transform(Item_transformer transformer, byte *arg) - { - return (this->*transformer)(arg); - } + virtual Item* transform(Item_transformer transformer, byte *arg); virtual void traverse_cond(Cond_traverser traverser, void *arg, traverse_order order) @@ -752,9 +749,10 @@ public: virtual bool find_item_in_field_list_processor(byte *arg) { return 0; } virtual bool change_context_processor(byte *context) { return 0; } virtual bool reset_query_id_processor(byte *query_id) { return 0; } + virtual bool is_expensive_processor(byte *arg) { return 0; } virtual Item *equal_fields_propagator(byte * arg) { return this; } - virtual Item *set_no_const_sub(byte *arg) { return this; } + virtual bool set_no_const_sub(byte *arg) { return FALSE; } virtual Item *replace_equal_field(byte * arg) { return this; } /* @@ -1254,7 +1252,7 @@ public: } Item_equal *find_item_equal(COND_EQUAL *cond_equal); Item *equal_fields_propagator(byte *arg); - Item *set_no_const_sub(byte *arg); + bool set_no_const_sub(byte *arg); Item *replace_equal_field(byte *arg); inline uint32 max_disp_length() { return field->max_length(); } Item_field *filed_for_view_update() { return this; } @@ -2115,18 +2113,7 @@ public: (this->*processor)(args); } - /* - This method like the walk method traverses the item tree, but - at the same time it can replace some nodes in the tree - */ - Item *transform(Item_transformer transformer, byte *args) - { - Item *new_item= arg->transform(transformer, args); - if (!new_item) - return 0; - arg= new_item; - return (this->*transformer)(args); - } + Item *transform(Item_transformer transformer, byte *args); }; /* diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 98453899375..919a23ed65d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -125,31 +125,39 @@ static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems) uchar null_byte; Field *field= NULL; - /* Search for date/time fields/functions */ - for (i= 0; i < nitems; i++) + /* + Do not convert items while creating a or showing a view in order + to store/display the original query in these cases. + */ + if (thd->lex->sql_command != SQLCOM_CREATE_VIEW && + thd->lex->sql_command != SQLCOM_SHOW_CREATE) { - if (!items[i]->result_as_longlong()) + /* Search for date/time fields/functions */ + for (i= 0; i < nitems; i++) { - /* Do not convert anything if a string field/function is present */ - if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT) + if (!items[i]->result_as_longlong()) + { + /* Do not convert anything if a string field/function is present */ + if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT) + { + i= nitems; + break; + } + continue; + } + if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM && + items[i]->result_type() != INT_RESULT) { - i= nitems; + field= ((Item_field *)items[i]->real_item())->field; + break; + } + else if (res == Item::FUNC_ITEM) + { + field= items[i]->tmp_table_field_from_field_type(0); + if (field) + field->move_field(buff, &null_byte, 0); break; } - continue; - } - if ((res= items[i]->real_item()->type()) == Item::FIELD_ITEM && - items[i]->result_type() != INT_RESULT) - { - field= ((Item_field *)items[i]->real_item())->field; - break; - } - else if (res == Item::FUNC_ITEM) - { - field= items[i]->tmp_table_field_from_field_type(0); - if (field) - field->move_field(buff, &null_byte, 0); - break; } } if (field) @@ -397,7 +405,8 @@ void Item_bool_func2::fix_length_and_dec() agg_arg_charsets(coll, args, 2, MY_COLL_CMP_CONV, 1)) return; - + args[0]->cmp_context= args[1]->cmp_context= + item_cmp_type(args[0]->result_type(), args[1]->result_type()); // Make a special case of compare with fields to get nicer DATE comparisons if (functype() == LIKE_FUNC) // Disable conversion in case of LIKE function. @@ -418,6 +427,7 @@ void Item_bool_func2::fix_length_and_dec() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. + args[0]->cmp_context= args[1]->cmp_context= INT_RESULT; return; } } @@ -432,6 +442,7 @@ void Item_bool_func2::fix_length_and_dec() { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. + args[0]->cmp_context= args[1]->cmp_context= INT_RESULT; return; } } @@ -500,8 +511,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) which would be transformed to: WHERE col= 'j' */ - (*a)->transform(&Item::set_no_const_sub, (byte*) 0); - (*b)->transform(&Item::set_no_const_sub, (byte*) 0); + (*a)->walk(&Item::set_no_const_sub, (byte*) 0); + (*b)->walk(&Item::set_no_const_sub, (byte*) 0); } break; } @@ -1209,6 +1220,7 @@ void Item_func_between::fix_length_and_dec() if (!args[0] || !args[1] || !args[2]) return; agg_cmp_type(thd, &cmp_type, args, 3); + args[0]->cmp_context= args[1]->cmp_context= args[2]->cmp_context= cmp_type; if (cmp_type == STRING_RESULT) agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV, 1); @@ -2753,6 +2765,8 @@ bool Item_cond::walk(Item_processor processor, byte *arg) Item *Item_cond::transform(Item_transformer transformer, byte *arg) { + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + List_iterator<Item> li(list); Item *item; while ((item= li++)) @@ -2760,8 +2774,15 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg) Item *new_item= item->transform(transformer, arg); if (!new_item) return 0; + + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ if (new_item != item) - li.replace(new_item); + current_thd->change_item_tree(li.ref(), new_item); } return Item_func::transform(transformer, arg); } @@ -3656,6 +3677,28 @@ Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */ } +Item *Item_func_nop_all::neg_transformer(THD *thd) +{ + /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */ + Item_func_not_all *new_item= new Item_func_not_all(args[0]); + Item_allany_subselect *allany= (Item_allany_subselect*)args[0]; + allany->func= allany->func_creator(FALSE); + allany->all= !allany->all; + allany->upper_item= new_item; + return new_item; +} + +Item *Item_func_not_all::neg_transformer(THD *thd) +{ + /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */ + Item_func_nop_all *new_item= new Item_func_nop_all(args[0]); + Item_allany_subselect *allany= (Item_allany_subselect*)args[0]; + allany->all= !allany->all; + allany->func= allany->func_creator(TRUE); + allany->upper_item= new_item; + return new_item; +} + Item *Item_func_eq::negated_item() /* a = b -> a != b */ { return new Item_func_ne(args[0], args[1]); @@ -3984,6 +4027,8 @@ bool Item_equal::walk(Item_processor processor, byte *arg) Item *Item_equal::transform(Item_transformer transformer, byte *arg) { + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + List_iterator<Item_field> it(fields); Item *item; while ((item= it++)) @@ -3991,8 +4036,15 @@ Item *Item_equal::transform(Item_transformer transformer, byte *arg) Item *new_item= item->transform(transformer, arg); if (!new_item) return 0; + + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ if (new_item != item) - it.replace((Item_field *) new_item); + current_thd->change_item_tree((Item **) it.ref(), new_item); } return Item_func::transform(transformer, arg); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index a2b10eacc79..47f9f2aa98f 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -311,6 +311,7 @@ public: void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; }; void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; }; bool empty_underlying_subquery(); + Item *neg_transformer(THD *thd); }; @@ -321,6 +322,7 @@ public: Item_func_nop_all(Item *a) :Item_func_not_all(a) {} longlong val_int(); const char *func_name() const { return "<nop>"; } + Item *neg_transformer(THD *thd); }; diff --git a/sql/item_create.cc b/sql/item_create.cc index 7d57757432e..e0e18094705 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -450,6 +450,7 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec, CHARSET_INFO *cs) { Item *res; + int tmp_len; LINT_INIT(res); switch (cast_type) { @@ -460,7 +461,13 @@ Item *create_func_cast(Item *a, Cast_target cast_type, int len, int dec, case ITEM_CAST_TIME: res= new Item_time_typecast(a); break; case ITEM_CAST_DATETIME: res= new Item_datetime_typecast(a); break; case ITEM_CAST_DECIMAL: - res= new Item_decimal_typecast(a, (len>0) ? len : 10, dec ? dec : 2); + tmp_len= (len>0) ? len : 10; + if (tmp_len < dec) + { + my_error(ER_M_BIGGER_THAN_D, MYF(0), ""); + return 0; + } + res= new Item_decimal_typecast(a, tmp_len, dec ? dec : 2); break; case ITEM_CAST_CHAR: res= new Item_char_typecast(a, len, cs ? cs : diff --git a/sql/item_func.cc b/sql/item_func.cc index 1d906b300b6..24f5eff197b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -258,6 +258,8 @@ void Item_func::traverse_cond(Cond_traverser traverser, Item *Item_func::transform(Item_transformer transformer, byte *argument) { + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + if (arg_count) { Item **arg,**arg_end; @@ -266,6 +268,13 @@ Item *Item_func::transform(Item_transformer transformer, byte *argument) Item *new_item= (*arg)->transform(transformer, argument); if (!new_item) return 0; + + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ if (*arg != new_item) current_thd->change_item_tree(arg, new_item); } @@ -398,6 +407,13 @@ Field *Item_func::tmp_table_field(TABLE *t_arg) return res; } + +bool Item_func::is_expensive_processor(byte *arg) +{ + return is_expensive(); +} + + my_decimal *Item_func::val_decimal(my_decimal *decimal_value) { DBUG_ASSERT(fixed); @@ -541,7 +557,7 @@ void Item_func::signal_divide_by_null() Item *Item_func::get_tmp_table_item(THD *thd) { - if (!with_sum_func && !const_item()) + if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC) return new Item_field(result_field); return copy_or_same(thd); } @@ -3406,6 +3422,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, entry->length=0; entry->update_query_id=0; entry->collation.set(NULL, DERIVATION_IMPLICIT); + entry->unsigned_flag= 0; /* If we are here, we were called from a SET or a query which sets a variable. Imagine it is this: @@ -3492,6 +3509,7 @@ Item_func_set_user_var::fix_length_and_dec() type - type of new value cs - charset info for new value dv - derivation for new value + unsigned_arg - indiates if a value of type INT_RESULT is unsigned RETURN VALUE False - success, True - failure @@ -3499,7 +3517,8 @@ Item_func_set_user_var::fix_length_and_dec() static bool update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, - Item_result type, CHARSET_INFO *cs, Derivation dv) + Item_result type, CHARSET_INFO *cs, Derivation dv, + bool unsigned_arg) { if (set_null) { @@ -3547,6 +3566,7 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, ((my_decimal*)entry->value)->fix_buffer_pointer(); entry->length= length; entry->collation.set(cs, dv); + entry->unsigned_flag= unsigned_arg; } entry->type=type; return 0; @@ -3555,7 +3575,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, bool Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, - CHARSET_INFO *cs, Derivation dv) + CHARSET_INFO *cs, Derivation dv, + bool unsigned_arg) { /* If we set a variable explicitely to NULL then keep the old @@ -3564,7 +3585,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, if ((null_value= args[0]->null_value) && null_item) type= entry->type; // Don't change type of item if (::update_hash(entry, (null_value= args[0]->null_value), - ptr, length, type, cs, dv)) + ptr, length, type, cs, dv, unsigned_arg)) { current_thd->fatal_error(); // Probably end of memory null_value= 1; @@ -3646,7 +3667,10 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, str->set(*(double*) value, decimals, &my_charset_bin); break; case INT_RESULT: - str->set(*(longlong*) value, &my_charset_bin); + if (!unsigned_flag) + str->set(*(longlong*) value, &my_charset_bin); + else + str->set(*(ulonglong*) value, &my_charset_bin); break; case DECIMAL_RESULT: my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str); @@ -3704,29 +3728,38 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val) */ bool -Item_func_set_user_var::check() +Item_func_set_user_var::check(bool use_result_field) { DBUG_ENTER("Item_func_set_user_var::check"); + if (use_result_field) + DBUG_ASSERT(result_field); switch (cached_result_type) { case REAL_RESULT: { - save_result.vreal= args[0]->val_real(); + save_result.vreal= use_result_field ? result_field->val_real() : + args[0]->val_real(); break; } case INT_RESULT: { - save_result.vint= args[0]->val_int(); + save_result.vint= use_result_field ? result_field->val_int() : + args[0]->val_int(); + unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag: + args[0]->unsigned_flag; break; } case STRING_RESULT: { - save_result.vstr= args[0]->val_str(&value); + save_result.vstr= use_result_field ? result_field->val_str(&value) : + args[0]->val_str(&value); break; } case DECIMAL_RESULT: { - save_result.vdec= args[0]->val_decimal(&decimal_buff); + save_result.vdec= use_result_field ? + result_field->val_decimal(&decimal_buff) : + args[0]->val_decimal(&decimal_buff); break; } case ROW_RESULT: @@ -3766,36 +3799,37 @@ Item_func_set_user_var::update() case REAL_RESULT: { res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal), - REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT); + REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0); break; } case INT_RESULT: { res= update_hash((void*) &save_result.vint, sizeof(save_result.vint), - INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT); + INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, + unsigned_flag); break; } case STRING_RESULT: { if (!save_result.vstr) // Null value res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin, - DERIVATION_IMPLICIT); + DERIVATION_IMPLICIT, 0); else res= update_hash((void*) save_result.vstr->ptr(), save_result.vstr->length(), STRING_RESULT, save_result.vstr->charset(), - DERIVATION_IMPLICIT); + DERIVATION_IMPLICIT, 0); break; } case DECIMAL_RESULT: { if (!save_result.vdec) // Null value res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin, - DERIVATION_IMPLICIT); + DERIVATION_IMPLICIT, 0); else res= update_hash((void*) save_result.vdec, sizeof(my_decimal), DECIMAL_RESULT, - &my_charset_bin, DERIVATION_IMPLICIT); + &my_charset_bin, DERIVATION_IMPLICIT, 0); break; } case ROW_RESULT: @@ -3811,7 +3845,7 @@ Item_func_set_user_var::update() double Item_func_set_user_var::val_real() { DBUG_ASSERT(fixed == 1); - check(); + check(0); update(); // Store expression return entry->val_real(&null_value); } @@ -3819,7 +3853,7 @@ double Item_func_set_user_var::val_real() longlong Item_func_set_user_var::val_int() { DBUG_ASSERT(fixed == 1); - check(); + check(0); update(); // Store expression return entry->val_int(&null_value); } @@ -3827,7 +3861,7 @@ longlong Item_func_set_user_var::val_int() String *Item_func_set_user_var::val_str(String *str) { DBUG_ASSERT(fixed == 1); - check(); + check(0); update(); // Store expression return entry->val_str(&null_value, str, decimals); } @@ -3836,7 +3870,7 @@ String *Item_func_set_user_var::val_str(String *str) my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val) { DBUG_ASSERT(fixed == 1); - check(); + check(0); update(); // Store expression return entry->val_decimal(&null_value, val); } @@ -3861,6 +3895,29 @@ void Item_func_set_user_var::print_as_stmt(String *str) str->append(')'); } +bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg) +{ + if (result_field) + { + check(1); + update(); + return protocol->store(result_field); + } + return Item::send(protocol, str_arg); +} + +void Item_func_set_user_var::make_field(Send_field *tmp_field) +{ + if (result_field) + { + result_field->make_field(tmp_field); + DBUG_ASSERT(tmp_field->table_name != 0); + if (Item::name) + tmp_field->col_name=Item::name; // Use user supplied name + } + else + Item::make_field(tmp_field); +} String * Item_func_get_user_var::val_str(String *str) @@ -4126,7 +4183,7 @@ bool Item_func_get_user_var::set_value(THD *thd, Item_func_set_user_var is not fixed after construction, call fix_fields(). */ - return (!suv || suv->fix_fields(thd, it) || suv->check() || suv->update()); + return (!suv || suv->fix_fields(thd, it) || suv->check(0) || suv->update()); } @@ -4151,7 +4208,7 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs) { if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, - DERIVATION_IMPLICIT)) + DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) current_thd->fatal_error(); // Probably end of memory } @@ -4160,7 +4217,7 @@ void Item_user_var_as_out_param::set_value(const char *str, uint length, CHARSET_INFO* cs) { if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs, - DERIVATION_IMPLICIT)) + DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) current_thd->fatal_error(); // Probably end of memory } @@ -4830,7 +4887,9 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) { bool err_status= TRUE; Sub_statement_state statement_state; - Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_security_ctx= thd->security_ctx; +#endif DBUG_ENTER("Item_func_sp::execute_impl"); @@ -4841,7 +4900,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) thd->security_ctx= context->security_ctx; } #endif - if (find_and_check_access(thd, EXECUTE_ACL, &save_ctx_func)) + if (find_and_check_access(thd)) goto error; /* @@ -4853,13 +4912,11 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld); thd->restore_sub_statement_state(&statement_state); -#ifndef NO_EMBEDDED_ACCESS_CHECKS - sp_restore_security_context(thd, save_ctx_func); error: +#ifndef NO_EMBEDDED_ACCESS_CHECKS thd->security_ctx= save_security_ctx; -#else -error: #endif + DBUG_RETURN(err_status); } @@ -4976,70 +5033,38 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) SYNOPSIS find_and_check_access() thd thread handler - want_access requested access - save backup of security context RETURN FALSE Access granted TRUE Requested access can't be granted or function doesn't exists - In this case security context is not changed and *save = 0 NOTES Checks if requested access to function can be granted to user. If function isn't found yet, it searches function first. If function can't be found or user don't have requested access error is raised. - If security context sp_ctx is provided and access can be granted then - switch back to previous context isn't performed. - In case of access error or if context is not provided then - find_and_check_access() switches back to previous security context. */ bool -Item_func_sp::find_and_check_access(THD *thd, ulong want_access, - Security_context **save) +Item_func_sp::find_and_check_access(THD *thd) { - bool res= TRUE; - - *save= 0; // Safety if error if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, &thd->sp_func_cache, TRUE))) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); - goto error; + return TRUE; } #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_routine_access(thd, want_access, - m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - goto error; - - sp_change_security_context(thd, m_sp, save); - /* - If we changed context to run as another user, we need to check the - access right for the new context again as someone may have deleted - this person the right to use the procedure - - TODO: - Cache if the definer has the right to use the object on the first - usage and only reset the cache if someone does a GRANT statement - that 'may' affect this. - */ - if (*save && - check_routine_access(thd, want_access, + if (check_routine_access(thd, EXECUTE_ACL, m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - { - sp_restore_security_context(thd, *save); - *save= 0; // Safety - goto error; - } + return TRUE; #endif - res= FALSE; // no error -error: - return res; + return FALSE; } + bool Item_func_sp::fix_fields(THD *thd, Item **ref) { @@ -5050,19 +5075,23 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) { /* Here we check privileges of the stored routine only during view - creation, in order to validate the view. A runtime check is perfomed - in Item_func_sp::execute(), and this method is not called during - context analysis. We do not need to restore the security context - changed in find_and_check_access because all view structures created - in CREATE VIEW are not used for execution. Notice, that during view - creation we do not infer into stored routine bodies and do not check - privileges of its statements, which would probably be a good idea - especially if the view has SQL SECURITY DEFINER and the used stored - procedure has SQL SECURITY DEFINER + creation, in order to validate the view. A runtime check is + perfomed in Item_func_sp::execute(), and this method is not + called during context analysis. Notice, that during view + creation we do not infer into stored routine bodies and do not + check privileges of its statements, which would probably be a + good idea especially if the view has SQL SECURITY DEFINER and + the used stored procedure has SQL SECURITY DEFINER. */ - Security_context *save_ctx; - if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx))) - sp_restore_security_context(thd, save_ctx); + res= find_and_check_access(thd); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_secutiry_ctx; + if (!res && !(res= set_routine_security_ctx(thd, m_sp, false, + &save_secutiry_ctx))) + { + sp_restore_security_context(thd, save_secutiry_ctx); + } +#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ } return res; } diff --git a/sql/item_func.h b/sql/item_func.h index c54fc701c53..8abf5d91cd5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -54,8 +54,8 @@ public: SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN, NOT_FUNC, NOT_ALL_FUNC, NOW_FUNC, TRIG_COND_FUNC, - GUSERVAR_FUNC, COLLATE_FUNC, - EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP }; + SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, + EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC }; enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } @@ -189,6 +189,8 @@ public: Item *transform(Item_transformer transformer, byte *arg); void traverse_cond(Cond_traverser traverser, void * arg, traverse_order order); + bool is_expensive_processor(byte *arg); + virtual bool is_expensive() { return 0; } }; @@ -933,6 +935,7 @@ public: Item_udf_func(udf_func *udf_arg, List<Item> &list) :Item_func(list), udf(udf_arg) {} const char *func_name() const { return udf.name(); } + enum Functype functype() const { return UDF_FUNC; } bool fix_fields(THD *thd, Item **ref) { DBUG_ASSERT(fixed == 0); @@ -945,6 +948,7 @@ public: void cleanup(); Item_result result_type () const { return udf.result_type(); } table_map not_null_tables() const { return 0; } + bool is_expensive() { return 1; } }; @@ -1157,21 +1161,22 @@ class Item_func_set_user_var :public Item_func String *vstr; my_decimal *vdec; } save_result; - String save_buff; - public: LEX_STRING name; // keep it public Item_func_set_user_var(LEX_STRING a,Item *b) :Item_func(b), cached_result_type(INT_RESULT), name(a) {} + enum Functype functype() const { return SUSERVAR_FUNC; } double val_real(); longlong val_int(); String *val_str(String *str); my_decimal *val_decimal(my_decimal *); - bool update_hash(void *ptr, uint length, enum Item_result type, - CHARSET_INFO *cs, Derivation dv); - bool check(); + bool update_hash(void *ptr, uint length, enum Item_result type, + CHARSET_INFO *cs, Derivation dv, bool unsigned_arg); + bool send(Protocol *protocol, String *str_arg); + void make_field(Send_field *tmp_field); + bool check(bool use_result_field); bool update(); enum Item_result result_type () const { return cached_result_type; } bool fix_fields(THD *thd, Item **ref); @@ -1468,11 +1473,11 @@ public: { context= (Name_resolution_context *)cntx; return FALSE; } void fix_length_and_dec(); - bool find_and_check_access(THD * thd, ulong want_access, - Security_context **backup); + bool find_and_check_access(THD * thd); virtual enum Functype functype() const { return FUNC_SP; } bool fix_fields(THD *thd, Item **ref); + bool is_expensive() { return 1; } }; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 2b92e72e728..c5200e26cb7 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -25,6 +25,12 @@ #ifdef HAVE_SPATIAL #include <m_ctype.h> +Field *Item_geometry_func::tmp_table_field(TABLE *t_arg) +{ + return new Field_geom(max_length, maybe_null, name, t_arg, + (Field::geometry_type) get_geometry_type()); +} + void Item_geometry_func::fix_length_and_dec() { collation.set(&my_charset_bin); @@ -32,6 +38,10 @@ void Item_geometry_func::fix_length_and_dec() max_length=MAX_BLOB_WIDTH; } +int Item_geometry_func::get_geometry_type() const +{ + return (int)Field::GEOM_GEOMETRY; +} String *Item_func_geometry_from_text::val_str(String *str) { @@ -152,6 +162,12 @@ String *Item_func_geometry_type::val_str(String *str) } +int Item_func_envelope::get_geometry_type() const +{ + return (int) Field::GEOM_POLYGON; +} + + String *Item_func_envelope::val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -176,6 +192,12 @@ String *Item_func_envelope::val_str(String *str) } +int Item_func_centroid::get_geometry_type() const +{ + return (int) Field::GEOM_POINT; +} + + String *Item_func_centroid::val_str(String *str) { DBUG_ASSERT(fixed == 1); @@ -310,6 +332,12 @@ err: */ +int Item_func_point::get_geometry_type() const +{ + return (int) Field::GEOM_POINT; +} + + String *Item_func_point::val_str(String *str) { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 1f64fdba609..4848f59301d 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -33,6 +33,8 @@ public: Item_geometry_func(List<Item> &list) :Item_str_func(list) {} void fix_length_and_dec(); enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; } + Field *tmp_table_field(TABLE *t_arg); + virtual int get_geometry_type() const; }; class Item_func_geometry_from_text: public Item_geometry_func @@ -89,6 +91,7 @@ public: Item_func_centroid(Item *a): Item_geometry_func(a) {} const char *func_name() const { return "centroid"; } String *val_str(String *); + int get_geometry_type() const; }; class Item_func_envelope: public Item_geometry_func @@ -97,6 +100,7 @@ public: Item_func_envelope(Item *a): Item_geometry_func(a) {} const char *func_name() const { return "envelope"; } String *val_str(String *); + int get_geometry_type() const; }; class Item_func_point: public Item_geometry_func @@ -106,6 +110,7 @@ public: Item_func_point(Item *a, Item *b, Item *srid): Item_geometry_func(a, b, srid) {} const char *func_name() const { return "point"; } String *val_str(String *); + int get_geometry_type() const; }; class Item_func_spatial_decomp: public Item_geometry_func diff --git a/sql/item_row.cc b/sql/item_row.cc index f5c8d511025..d7591b9865d 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -154,12 +154,22 @@ bool Item_row::walk(Item_processor processor, byte *arg) Item *Item_row::transform(Item_transformer transformer, byte *arg) { + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + for (uint i= 0; i < arg_count; i++) { Item *new_item= items[i]->transform(transformer, arg); if (!new_item) return 0; - items[i]= new_item; + + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ + if (items[i] != new_item) + current_thd->change_item_tree(&items[i], new_item); } return (this->*transformer)(arg); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 5ceb462385c..46a96c28d88 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -124,6 +124,7 @@ String *Item_func_md5::val_str(String *str) { DBUG_ASSERT(fixed == 1); String * sptr= args[0]->val_str(str); + str->set_charset(&my_charset_bin); if (sptr) { my_MD5_CTX context; @@ -170,6 +171,7 @@ String *Item_func_sha::val_str(String *str) { DBUG_ASSERT(fixed == 1); String * sptr= args[0]->val_str(str); + str->set_charset(&my_charset_bin); if (sptr) /* If we got value different from NULL */ { SHA1_CONTEXT context; /* Context used to generate SHA1 hash */ @@ -1503,6 +1505,23 @@ void Item_func_trim::fix_length_and_dec() } } +void Item_func_trim::print(String *str) +{ + if (arg_count == 1) + { + Item_func::print(str); + return; + } + str->append(Item_func_trim::func_name()); + str->append('('); + str->append(mode_name()); + str->append(' '); + args[1]->print(str); + str->append(STRING_WITH_LEN(" from ")); + args[0]->print(str); + str->append(')'); +} + /* Item_func_password */ @@ -1588,7 +1607,7 @@ String *Item_func_encrypt::val_str(String *str) null_value= 1; return 0; } - str->set(tmp,(uint) strlen(tmp),res->charset()); + str->set(tmp, (uint) strlen(tmp), &my_charset_bin); str->copy(); pthread_mutex_unlock(&LOCK_crypt); return str; @@ -2024,7 +2043,7 @@ String *Item_func_make_set::val_str(String *str) return &my_empty_string; result= &tmp_str; } - if (tmp_str.append(',') || tmp_str.append(*res)) + if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res)) return &my_empty_string; } } @@ -2034,6 +2053,26 @@ String *Item_func_make_set::val_str(String *str) } +Item *Item_func_make_set::transform(Item_transformer transformer, byte *arg) +{ + DBUG_ASSERT(!current_thd->is_stmt_prepare()); + + Item *new_item= item->transform(transformer, arg); + if (!new_item) + return 0; + + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ + if (item != new_item) + current_thd->change_item_tree(&item, new_item); + return Item_str_func::transform(transformer, arg); +} + + void Item_func_make_set::print(String *str) { str->append(STRING_WITH_LEN("make_set(")); @@ -2342,17 +2381,33 @@ String *Item_func_conv::val_str(String *str) abs(to_base) > 36 || abs(to_base) < 2 || abs(from_base) > 36 || abs(from_base) < 2 || !(res->length())) { - null_value=1; - return 0; + null_value= 1; + return NULL; } - null_value=0; + null_value= 0; unsigned_flag= !(from_base < 0); - if (from_base < 0) - dec= my_strntoll(res->charset(),res->ptr(),res->length(),-from_base,&endptr,&err); + + if (args[0]->field_type() == MYSQL_TYPE_BIT) + { + /* + Special case: The string representation of BIT doesn't resemble the + decimal representation, so we shouldn't change it to string and then to + decimal. + */ + dec= args[0]->val_int(); + } else - dec= (longlong) my_strntoull(res->charset(),res->ptr(),res->length(),from_base,&endptr,&err); - ptr= longlong2str(dec,ans,to_base); - if (str->copy(ans,(uint32) (ptr-ans), default_charset())) + { + if (from_base < 0) + dec= my_strntoll(res->charset(), res->ptr(), res->length(), + -from_base, &endptr, &err); + else + dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(), + from_base, &endptr, &err); + } + + ptr= longlong2str(dec, ans, to_base); + if (str->copy(ans, (uint32) (ptr-ans), default_charset())) return &my_empty_string; return str; } @@ -2682,8 +2737,12 @@ String* Item_func_export_set::val_str(String* str) } break; case 3: - sep_buf.set(STRING_WITH_LEN(","), default_charset()); - sep = &sep_buf; + { + /* errors is not checked - assume "," can always be converted */ + uint errors; + sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors); + sep = &sep_buf; + } break; default: DBUG_ASSERT(0); // cannot happen @@ -2968,6 +3027,16 @@ String *Item_func_uncompress::val_str(String *str) if (res->is_empty()) return res; + /* If length is less than 4 bytes, data is corrupt */ + if (res->length() <= 4) + { + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ZLIB_Z_DATA_ERROR, + ER(ER_ZLIB_Z_DATA_ERROR)); + goto err; + } + + /* Size of uncompressed data is stored as first 4 bytes of field */ new_size= uint4korr(res->ptr()) & 0x3FFFFFFF; if (new_size > current_thd->variables.max_allowed_packet) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 46b1b2fc248..528180b803d 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -43,7 +43,10 @@ class Item_func_md5 :public Item_str_func { String tmp_value; public: - Item_func_md5(Item *a) :Item_str_func(a) {} + Item_func_md5(Item *a) :Item_str_func(a) + { + collation.set(&my_charset_bin); + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "md5"; } @@ -53,7 +56,10 @@ public: class Item_func_sha :public Item_str_func { public: - Item_func_sha(Item *a) :Item_str_func(a) {} + Item_func_sha(Item *a) :Item_str_func(a) + { + collation.set(&my_charset_bin); + } String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "sha"; } @@ -233,6 +239,8 @@ public: String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "trim"; } + void print(String *str); + virtual const char *mode_name() const { return "both"; } }; @@ -243,6 +251,7 @@ public: Item_func_ltrim(Item *a) :Item_func_trim(a) {} String *val_str(String *); const char *func_name() const { return "ltrim"; } + const char *mode_name() const { return "leading"; } }; @@ -253,6 +262,7 @@ public: Item_func_rtrim(Item *a) :Item_func_trim(a) {} String *val_str(String *); const char *func_name() const { return "rtrim"; } + const char *mode_name() const { return "trailing"; } }; @@ -321,9 +331,21 @@ public: class Item_func_encrypt :public Item_str_func { String tmp_value; + + /* Encapsulate common constructor actions */ + void constructor_helper() + { + collation.set(&my_charset_bin); + } public: - Item_func_encrypt(Item *a) :Item_str_func(a) {} - Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) {} + Item_func_encrypt(Item *a) :Item_str_func(a) + { + constructor_helper(); + } + Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) + { + constructor_helper(); + } String *val_str(String *); void fix_length_and_dec() { maybe_null=1; max_length = 13; } const char *func_name() const { return "encrypt"; } @@ -471,14 +493,7 @@ public: return item->walk(processor, arg) || Item_str_func::walk(processor, arg); } - Item *transform(Item_transformer transformer, byte *arg) - { - Item *new_item= item->transform(transformer, arg); - if (!new_item) - return 0; - item= new_item; - return Item_str_func::transform(transformer, arg); - } + Item *transform(Item_transformer transformer, byte *arg); void print(String *str); }; @@ -724,7 +739,7 @@ public: void fix_length_and_dec(); bool eq(const Item *item, bool binary_cmp) const; const char *func_name() const { return "collate"; } - enum Functype func_type() const { return COLLATE_FUNC; } + enum Functype functype() const { return COLLATE_FUNC; } void print(String *str); Item_field *filed_for_view_update() { @@ -804,7 +819,7 @@ class Item_func_uncompress: public Item_str_func String buffer; public: Item_func_uncompress(Item *a): Item_str_func(a){} - void fix_length_and_dec(){max_length= MAX_BLOB_WIDTH;} + void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } const char *func_name() const{return "uncompress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 5404021a348..0ad517609c9 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -572,14 +572,14 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, } Item_allany_subselect::Item_allany_subselect(Item * left_exp, - Comp_creator *fn, + chooser_compare_func_creator fc, st_select_lex *select_lex, bool all_arg) - :Item_in_subselect(), all(all_arg) + :Item_in_subselect(), func_creator(fc), all(all_arg) { DBUG_ENTER("Item_in_subselect::Item_in_subselect"); left_expr= left_exp; - func= fn; + func= func_creator(all_arg); init(select_lex, new select_exists_subselect(this)); max_columns= 1; abort_on_null= 0; @@ -1098,24 +1098,23 @@ Item_in_subselect::row_value_transformer(JOIN *join) DBUG_RETURN(RES_ERROR); Item *item_eq= new Item_func_eq(new - Item_direct_ref(&select_lex->context, - (*optimizer->get_cache())-> - addr(i), - (char *)"<no matter>", - (char *)in_left_expr_name), + Item_ref(&select_lex->context, + (*optimizer->get_cache())-> + addr(i), + (char *)"<no matter>", + (char *)in_left_expr_name), new - Item_direct_ref(&select_lex->context, - select_lex->ref_pointer_array + i, - (char *)"<no matter>", - (char *)"<list ref>") + Item_ref(&select_lex->context, + select_lex->ref_pointer_array + i, + (char *)"<no matter>", + (char *)"<list ref>") ); Item *item_isnull= new Item_func_isnull(new - Item_direct_ref(&select_lex->context, - select_lex-> - ref_pointer_array+i, - (char *)"<no matter>", - (char *)"<list ref>") + Item_ref(&select_lex->context, + select_lex->ref_pointer_array+i, + (char *)"<no matter>", + (char *)"<list ref>") ); having_item= and_items(having_item, @@ -1125,11 +1124,11 @@ Item_in_subselect::row_value_transformer(JOIN *join) new Item_is_not_null_test(this, new - Item_direct_ref(&select_lex->context, - select_lex-> - ref_pointer_array + i, - (char *)"<no matter>", - (char *)"<list ref>") + Item_ref(&select_lex->context, + select_lex-> + ref_pointer_array + i, + (char *)"<no matter>", + (char *)"<list ref>") ) ); item_having_part2->top_level_item(); @@ -1185,11 +1184,11 @@ Item_in_subselect::row_value_transformer(JOIN *join) new Item_is_not_null_test(this, new - Item_direct_ref(&select_lex->context, - select_lex-> - ref_pointer_array + i, - (char *)"<no matter>", - (char *)"<list ref>") + Item_ref(&select_lex->context, + select_lex-> + ref_pointer_array + i, + (char *)"<no matter>", + (char *)"<list ref>") ) ); item_isnull= new @@ -1511,6 +1510,7 @@ static Item_result set_row(List<Item> &item_list, Item *item, item->max_length= sel_item->max_length; res_type= sel_item->result_type(); item->decimals= sel_item->decimals; + item->unsigned_flag= sel_item->unsigned_flag; *maybe_null= sel_item->maybe_null; if (!(row[i]= Item_cache::get_cache(res_type))) return STRING_RESULT; // we should return something diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 293408dc09e..45df4f3880d 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -269,14 +269,13 @@ public: /* ALL/ANY/SOME subselect */ class Item_allany_subselect :public Item_in_subselect { -protected: - Comp_creator *func; - public: + chooser_compare_func_creator func_creator; + Comp_creator *func; bool all; - Item_allany_subselect(Item * left_expr, Comp_creator *f, - st_select_lex *select_lex, bool all); + Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc, + st_select_lex *select_lex, bool all); // only ALL subquery has upper not subs_type substype() { return all?ALL_SUBS:ANY_SUBS; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 4d70debb966..bcd8270e52f 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -290,7 +290,9 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): void Item_sum::mark_as_sum_func() { - current_thd->lex->current_select->with_sum_func= 1; + SELECT_LEX *cur_select= current_thd->lex->current_select; + cur_select->n_sum_items++; + cur_select->with_sum_func= 1; with_sum_func= 1; } @@ -377,7 +379,13 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table, case INT_RESULT: return new Field_longlong(max_length,maybe_null,name,table,unsigned_flag); case STRING_RESULT: - if (max_length/collation.collation->mbmaxlen > 255 && convert_blob_length) + /* + Make sure that the blob fits into a Field_varstring which has + 2-byte lenght. + */ + if (max_length/collation.collation->mbmaxlen > 255 && + max_length/collation.collation->mbmaxlen < UINT_MAX16 && + convert_blob_length) return new Field_varstring(convert_blob_length, maybe_null, name, table, collation.collation); @@ -1256,9 +1264,6 @@ Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table, sizeof(double)*2) + sizeof(longlong), 0, name, table, &my_charset_bin); } - if (hybrid_type == DECIMAL_RESULT) - return new Field_new_decimal(max_length, maybe_null, name, table, - decimals, unsigned_flag); return new Field_double(max_length, maybe_null,name,table,decimals); } diff --git a/sql/item_sum.h b/sql/item_sum.h index f4ff257aa4e..f1ea95214de 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -688,7 +688,7 @@ public: { return sample ? "var_samp(" : "variance("; } Item *copy_or_same(THD* thd); Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length); - enum Item_result result_type () const { return hybrid_type; } + enum Item_result result_type () const { return REAL_RESULT; } }; class Item_sum_std; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 9e1962835c8..30230005f6e 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -224,7 +224,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, tmp= (char*) val + min(2, val_len); l_time->day= (int) my_strtoll10(val, &tmp, &error); /* Skip 'st, 'nd, 'th .. */ - val= tmp + min((int) (end-tmp), 2); + val= tmp + min((int) (val_end-tmp), 2); break; /* Hour */ @@ -1704,14 +1704,12 @@ uint Item_func_date_format::format_length(const String *format) case 'u': /* week (00..52), where week starts with Monday */ case 'V': /* week 1..53 used with 'x' */ case 'v': /* week 1..53 used with 'x', where week starts with Monday */ - case 'H': /* hour (00..23) */ case 'y': /* year, numeric, 2 digits */ case 'm': /* month, numeric */ case 'd': /* day (of the month), numeric */ case 'h': /* hour (01..12) */ case 'I': /* --||-- */ case 'i': /* minutes, numeric */ - case 'k': /* hour ( 0..23) */ case 'l': /* hour ( 1..12) */ case 'p': /* locale's AM or PM */ case 'S': /* second (00..61) */ @@ -1720,6 +1718,10 @@ uint Item_func_date_format::format_length(const String *format) case 'e': /* day (0..31) */ size += 2; break; + case 'k': /* hour ( 0..23) */ + case 'H': /* hour (00..23; value > 23 OK, padding always 2-digit) */ + size += 7; /* docs allow > 23, range depends on sizeof(unsigned int) */ + break; case 'r': /* time, 12-hour (hh:mm:ss [AP]M) */ size += 11; break; @@ -2877,6 +2879,8 @@ longlong Item_func_timestamp_diff::val_int() { uint year_beg, year_end, month_beg, month_end, day_beg, day_end; uint years= 0; + uint second_beg, second_end, microsecond_beg, microsecond_end; + if (neg == -1) { year_beg= ltime2.year; @@ -2885,6 +2889,10 @@ longlong Item_func_timestamp_diff::val_int() month_end= ltime1.month; day_beg= ltime2.day; day_end= ltime1.day; + second_beg= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second; + second_end= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second; + microsecond_beg= ltime2.second_part; + microsecond_end= ltime1.second_part; } else { @@ -2894,6 +2902,10 @@ longlong Item_func_timestamp_diff::val_int() month_end= ltime2.month; day_beg= ltime1.day; day_end= ltime2.day; + second_beg= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second; + second_end= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second; + microsecond_beg= ltime1.second_part; + microsecond_end= ltime2.second_part; } /* calc years */ @@ -2907,8 +2919,13 @@ longlong Item_func_timestamp_diff::val_int() months+= 12 - (month_beg - month_end); else months+= (month_end - month_beg); + if (day_end < day_beg) months-= 1; + else if ((day_end == day_beg) && + ((second_end < second_beg) || + (second_end == second_beg && microsecond_end < microsecond_beg))) + months-= 1; } switch (int_type) { diff --git a/sql/lock.cc b/sql/lock.cc index 97a080c5634..90ddcc957a2 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -854,6 +854,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) TABLE *table; char key[MAX_DBKEY_LENGTH]; char *db= table_list->db; + int table_in_key_offset; uint key_length; HASH_SEARCH_STATE state; DBUG_ENTER("lock_table_name"); @@ -861,8 +862,9 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) safe_mutex_assert_owner(&LOCK_open); - key_length=(uint) (strmov(strmov(key,db)+1,table_list->table_name) - -key)+ 1; + table_in_key_offset= strmov(key, db) - key + 1; + key_length= (uint)(strmov(key + table_in_key_offset, table_list->table_name) + - key) + 1; /* Only insert the table if we haven't insert it already */ @@ -883,6 +885,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) table->s= &table->share_not_to_be_used; memcpy((table->s->table_cache_key= (char*) (table+1)), key, key_length); table->s->db= table->s->table_cache_key; + table->s->table_name= table->s->table_cache_key + table_in_key_offset; table->s->key_length=key_length; table->in_use=thd; table->locked_by_name=1; diff --git a/sql/log.cc b/sql/log.cc index ebd1d10d8b7..1cd01865f9f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -723,13 +723,18 @@ shutdown the MySQL server and restart it.", name, errno); int MYSQL_LOG::get_current_log(LOG_INFO* linfo) { pthread_mutex_lock(&LOCK_log); + int ret = raw_get_current_log(linfo); + pthread_mutex_unlock(&LOCK_log); + return ret; +} + +int MYSQL_LOG::raw_get_current_log(LOG_INFO* linfo) +{ strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1); linfo->pos = my_b_tell(&log_file); - pthread_mutex_unlock(&LOCK_log); return 0; } - /* Move all data up in a file in an filename index file @@ -2385,6 +2390,12 @@ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, void */ +#ifdef EMBEDDED_LIBRARY +void vprint_msg_to_log(enum loglevel level __attribute__((unused)), + const char *format __attribute__((unused)), + va_list argsi __attribute__((unused))) +{} +#else /*!EMBEDDED_LIBRARY*/ void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) { char buff[1024]; @@ -2400,6 +2411,7 @@ void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) DBUG_VOID_RETURN; } +#endif /*EMBEDDED_LIBRARY*/ void sql_print_error(const char *format, ...) diff --git a/sql/log_event.cc b/sql/log_event.cc index cf5dbb1e77c..219434ab218 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3846,7 +3846,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli) a single record and with a single column. Thus, like a column value, it could always have IMPLICIT derivation. */ - e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT); + e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0); free_root(thd->mem_root,0); rli->inc_event_relay_log_pos(); diff --git a/sql/message.mc b/sql/message.mc new file mode 100644 index 00000000000..a1a7c8cff7e --- /dev/null +++ b/sql/message.mc @@ -0,0 +1,8 @@ +MessageId = 100 +Severity = Error +Facility = Application +SymbolicName = MSG_DEFAULT +Language = English +%1For more information, see Help and Support Center at http://www.mysql.com. + + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 089bc965c8c..d73b1f1aac0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -105,6 +105,15 @@ typedef struct my_locale_st TYPELIB *ab_month_names; TYPELIB *day_names; TYPELIB *ab_day_names; +#ifdef __cplusplus + my_locale_st(const char *name_par, const char *descr_par, bool is_ascii_par, + TYPELIB *month_names_par, TYPELIB *ab_month_names_par, + TYPELIB *day_names_par, TYPELIB *ab_day_names_par) : + name(name_par), description(descr_par), is_ascii(is_ascii_par), + month_names(month_names_par), ab_month_names(ab_month_names_par), + day_names(day_names_par), ab_day_names(ab_day_names_par) + {} +#endif } MY_LOCALE; extern MY_LOCALE my_locale_en_US; @@ -520,9 +529,11 @@ enum enum_var_type OPT_DEFAULT= 0, OPT_SESSION, OPT_GLOBAL }; class sys_var; +class Comp_creator; +typedef Comp_creator* (*chooser_compare_func_creator)(bool invert); #include "item.h" extern my_decimal decimal_zero; -typedef Comp_creator* (*chooser_compare_func_creator)(bool invert); + /* sql_parse.cc */ void free_items(Item *item); void cleanup_items(Item *item); @@ -555,6 +566,8 @@ void get_default_definer(THD *thd, LEX_USER *definer); LEX_USER *create_default_definer(THD *thd); LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name); LEX_USER *get_current_user(THD *thd, LEX_USER *user); +bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str, + const char *err_msg, uint max_length); enum enum_mysql_completiontype { ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7, @@ -865,8 +878,6 @@ bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); -int mysql_find_files(THD *thd,List<char> *files, const char *db, - const char *path, const char *wild, bool dir); bool mysqld_show_storage_engines(THD *thd); bool mysqld_show_privileges(THD *thd); bool mysqld_show_column_types(THD *thd); @@ -974,6 +985,7 @@ bool setup_tables_and_check_access (THD *thd, TABLE_LIST *tables, Item **conds, TABLE_LIST **leaves, bool select_insert, + ulong want_access_first, ulong want_access); int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields, List<Item> *sum_func_list, uint wild_num); @@ -1138,7 +1150,10 @@ uint check_word(TYPELIB *lib, const char *val, const char *end, bool is_keyword(const char *name, uint len); #define MY_DB_OPT_FILE "db.opt" +bool check_db_dir_existence(const char *db_name); bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create); +bool load_db_opt_by_name(THD *thd, const char *db_name, + HA_CREATE_INFO *db_create_info); bool my_dbopt_init(void); void my_dbopt_cleanup(void); void my_dbopt_free(void); @@ -1498,6 +1513,9 @@ void free_list(I_List <i_string> *list); /* sql_yacc.cc */ extern int MYSQLparse(void *thd); +#ifndef DBUG_OFF +extern void turn_parser_debug_on(); +#endif /* frm_crypt.cc */ #ifdef HAVE_CRYPTED_FRM diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fc5cba4b5ec..8a4f212340d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -713,7 +713,7 @@ static void close_connections(void) { if (ip_sock != INVALID_SOCKET) { - (void) shutdown(ip_sock,2); + (void) shutdown(ip_sock, SHUT_RDWR); (void) closesocket(ip_sock); ip_sock= INVALID_SOCKET; } @@ -745,7 +745,7 @@ static void close_connections(void) #ifdef HAVE_SYS_UN_H if (unix_sock != INVALID_SOCKET) { - (void) shutdown(unix_sock,2); + (void) shutdown(unix_sock, SHUT_RDWR); (void) closesocket(unix_sock); (void) unlink(mysqld_unix_port); unix_sock= INVALID_SOCKET; @@ -848,7 +848,7 @@ static void close_server_sock() { ip_sock=INVALID_SOCKET; DBUG_PRINT("info",("calling shutdown on TCP/IP socket")); - VOID(shutdown(tmp_sock,2)); + VOID(shutdown(tmp_sock, SHUT_RDWR)); #if defined(__NETWARE__) /* The following code is disabled for normal systems as it causes MySQL @@ -863,7 +863,7 @@ static void close_server_sock() { unix_sock=INVALID_SOCKET; DBUG_PRINT("info",("calling shutdown on unix socket")); - VOID(shutdown(tmp_sock,2)); + VOID(shutdown(tmp_sock, SHUT_RDWR)); #if defined(__NETWARE__) /* The following code is disabled for normal systems as it may cause MySQL @@ -1409,7 +1409,7 @@ static void network_init(void) uint waited; uint this_wait; uint retry; - DBUG_ENTER("server_init"); + DBUG_ENTER("network_init"); LINT_INIT(ret); set_ports(); @@ -2392,10 +2392,8 @@ static int my_message_sql(uint error, const char *str, myf MyFlags) if ((thd= current_thd)) { if (thd->spcont && - thd->spcont->find_handler(error, MYSQL_ERROR::WARN_LEVEL_ERROR)) + thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd)) { - if (! thd->spcont->found_handler_here()) - thd->net.report_error= 1; /* Make "select" abort correctly */ DBUG_RETURN(0); } @@ -2738,9 +2736,8 @@ static int init_common_variables(const char *conf_file_name, int argc, get corrupted if accesses with names of different case. */ DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names)); - if (!lower_case_table_names && - (lower_case_file_system= - (test_if_case_insensitive(mysql_real_data_home) == 1))) + lower_case_file_system= test_if_case_insensitive(mysql_real_data_home); + if (!lower_case_table_names && lower_case_file_system == 1) { if (lower_case_table_names_used) { @@ -2770,6 +2767,11 @@ You should consider changing lower_case_table_names to 1 or 2", mysql_real_data_home); lower_case_table_names= 0; } + else + { + lower_case_file_system= + (test_if_case_insensitive(mysql_real_data_home) == 1); + } /* Reset table_alias_charset, now that lower_case_table_names is set. */ table_alias_charset= (lower_case_table_names ? @@ -4086,7 +4088,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (req.sink) ((void (*)(int))req.sink)(req.fd); - (void) shutdown(new_sock,2); + (void) shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -4101,7 +4103,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (getsockname(new_sock,&dummy, &dummyLen) < 0) { sql_perror("Error on new connection socket"); - (void) shutdown(new_sock,2); + (void) shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); continue; } @@ -4113,7 +4115,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) if (!(thd= new THD)) { - (void) shutdown(new_sock,2); + (void) shutdown(new_sock, SHUT_RDWR); VOID(closesocket(new_sock)); continue; } @@ -4127,7 +4129,7 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) vio_delete(vio_tmp); else { - (void) shutdown(new_sock,2); + (void) shutdown(new_sock, SHUT_RDWR); (void) closesocket(new_sock); } delete thd; diff --git a/sql/net_serv.cc b/sql/net_serv.cc index cf9dc6e3f60..1601f7e5177 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -96,8 +96,11 @@ extern uint test_flags; extern ulong bytes_sent, bytes_received, net_big_packet_count; extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; #ifndef MYSQL_INSTANCE_MANAGER -extern void query_cache_insert(NET *net, const char *packet, ulong length); +#ifdef HAVE_QUERY_CACHE #define USE_QUERY_CACHE +extern void query_cache_init_query(NET *net); +extern void query_cache_insert(NET *net, const char *packet, ulong length); +#endif // HAVE_QUERY_CACHE #define update_statistics(A) A #endif /* MYSQL_INSTANCE_MANGER */ #endif /* defined(MYSQL_SERVER) && !defined(MYSQL_INSTANCE_MANAGER) */ @@ -133,7 +136,11 @@ my_bool my_net_init(NET *net, Vio* vio) net->compress=0; net->reading_or_writing=0; net->where_b = net->remain_in_buf=0; net->last_errno=0; - net->query_cache_query=0; +#ifdef USE_QUERY_CACHE + query_cache_init_query(net); +#else + net->query_cache_query= 0; +#endif net->report_error= 0; if (vio != 0) /* If real connection */ @@ -552,10 +559,8 @@ net_real_write(NET *net,const char *packet,ulong len) my_bool net_blocking = vio_is_blocking(net->vio); DBUG_ENTER("net_real_write"); -#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE) \ - && !defined(MYSQL_INSTANCE_MANAGER) - if (net->query_cache_query != 0) - query_cache_insert(net, packet, len); +#if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE) + query_cache_insert(net, packet, len); #endif if (net->error == 2) @@ -855,7 +860,7 @@ my_real_read(NET *net, ulong *complen) #endif /* EXTRA_DEBUG */ } #if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) - if (vio_should_retry(net->vio)) + if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted read. Retrying...")); continue; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3b77d1b419e..6189d0412b3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -442,6 +442,7 @@ typedef struct st_qsel_param { uint fields_bitmap_size; MY_BITMAP needed_fields; /* bitmask of fields needed by the query */ + MY_BITMAP tmp_covered_fields; key_map *needed_reg; /* ptr to SQL_SELECT::needed_reg */ @@ -1765,6 +1766,7 @@ static int fill_used_fields_bitmap(PARAM *param) param->fields_bitmap_size= (table->s->fields/8 + 1); uchar *tmp; uint pk; + param->tmp_covered_fields.bitmap= 0; if (!(tmp= (uchar*)alloc_root(param->mem_root,param->fields_bitmap_size)) || bitmap_init(¶m->needed_fields, tmp, param->fields_bitmap_size*8, FALSE)) @@ -3202,11 +3204,14 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, /*I=set of all covering indexes */ ror_scan_mark= tree->ror_scans; - uchar buf[MAX_KEY/8+1]; - MY_BITMAP covered_fields; - if (bitmap_init(&covered_fields, buf, nbits, FALSE)) + MY_BITMAP *covered_fields= ¶m->tmp_covered_fields; + if (!covered_fields->bitmap) + covered_fields->bitmap= (uchar*)alloc_root(param->mem_root, + param->fields_bitmap_size); + if (!covered_fields->bitmap || + bitmap_init(covered_fields, covered_fields->bitmap, nbits, FALSE)) DBUG_RETURN(0); - bitmap_clear_all(&covered_fields); + bitmap_clear_all(covered_fields); double total_cost= 0.0f; ha_rows records=0; @@ -3225,7 +3230,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, */ for (ROR_SCAN_INFO **scan= ror_scan_mark; scan != ror_scans_end; ++scan) { - bitmap_subtract(&(*scan)->covered_fields, &covered_fields); + bitmap_subtract(&(*scan)->covered_fields, covered_fields); (*scan)->used_fields_covered= bitmap_bits_set(&(*scan)->covered_fields); (*scan)->first_uncovered_field= @@ -3247,8 +3252,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param, if (total_cost > read_time) DBUG_RETURN(NULL); /* F=F-covered by first(I) */ - bitmap_union(&covered_fields, &(*ror_scan_mark)->covered_fields); - all_covered= bitmap_is_subset(¶m->needed_fields, &covered_fields); + bitmap_union(covered_fields, &(*ror_scan_mark)->covered_fields); + all_covered= bitmap_is_subset(¶m->needed_fields, covered_fields); } while ((++ror_scan_mark < ror_scans_end) && !all_covered); if (!all_covered || (ror_scan_mark - tree->ror_scans) == 1) @@ -3580,25 +3585,37 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, break; case Item_func::BETWEEN: - if (inv) - { - tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1], - cond_func->arguments()[2], cmp_type); - } - else + { + if (!value) { - tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC, - cond_func->arguments()[1],cmp_type); - if (tree) + if (inv) + { + tree= get_ne_mm_tree(param, cond_func, field, cond_func->arguments()[1], + cond_func->arguments()[2], cmp_type); + } + else { - tree= tree_and(param, tree, get_mm_parts(param, cond_func, field, - Item_func::LE_FUNC, - cond_func->arguments()[2], - cmp_type)); + tree= get_mm_parts(param, cond_func, field, Item_func::GE_FUNC, + cond_func->arguments()[1],cmp_type); + if (tree) + { + tree= tree_and(param, tree, get_mm_parts(param, cond_func, field, + Item_func::LE_FUNC, + cond_func->arguments()[2], + cmp_type)); + } } } + else + tree= get_mm_parts(param, cond_func, field, + (inv ? + (value == (Item*)1 ? Item_func::GT_FUNC : + Item_func::LT_FUNC): + (value == (Item*)1 ? Item_func::LE_FUNC : + Item_func::GE_FUNC)), + cond_func->arguments()[0], cmp_type); break; - + } case Item_func::IN_FUNC: { Item_func_in *func=(Item_func_in*) cond_func; @@ -3608,41 +3625,33 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, if (func->array && func->cmp_type != ROW_RESULT) { /* - We get here for conditions in form "t.key NOT IN (c1, c2, ...)" - (where c{i} are constants). - Our goal is to produce a SEL_ARG graph that represents intervals: + We get here for conditions in form "t.key NOT IN (c1, c2, ...)", + where c{i} are constants. Our goal is to produce a SEL_TREE that + represents intervals: ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ... (*) where $MIN is either "-inf" or NULL. - The most straightforward way to handle NOT IN would be to convert - it to "(t.key != c1) AND (t.key != c2) AND ..." and let the range - optimizer to build SEL_ARG graph from that. However that will cause - the range optimizer to use O(N^2) memory (it's a bug, not filed), - and people do use big NOT IN lists (see BUG#15872). Also, for big - NOT IN lists constructing/using graph (*) does not make the query - faster. - - So, we will handle NOT IN manually in the following way: - * if the number of entries in the NOT IN list is less then - NOT_IN_IGNORE_THRESHOLD, we will construct SEL_ARG graph (*) - manually. - * Otherwise, we will construct a smaller graph: for - "t.key NOT IN (c1,...cN)" we construct a graph representing - ($MIN < t.key) OR (cN < t.key) // here sequence of c_i is - // ordered. - - A note about partially-covering indexes: for those (e.g. for - "a CHAR(10), KEY(a(5))") the handling is correct (albeit not very - efficient): - Instead of "t.key < c1" we get "t.key <= prefix-val(c1)". - Combining the intervals in (*) together, we get: - (-inf<=t.key<=c1) OR (c1<=t.key<=c2) OR (c2<=t.key<=c3) OR ... - i.e. actually we get intervals combined into one interval: - (-inf<=t.key<=+inf). This doesn't make much sense but it doesn't - cause any problems. + The most straightforward way to produce it is to convert NOT IN + into "(t.key != c1) AND (t.key != c2) AND ... " and let the range + analyzer to build SEL_TREE from that. The problem is that the + range analyzer will use O(N^2) memory (which is probably a bug), + and people do use big NOT IN lists (e.g. see BUG#15872, BUG#21282), + will run out of memory. + + Another problem with big lists like (*) is that a big list is + unlikely to produce a good "range" access, while considering that + range access will require expensive CPU calculations (and for + MyISAM even index accesses). In short, big NOT IN lists are rarely + worth analyzing. + + Considering the above, we'll handle NOT IN as follows: + * if the number of entries in the NOT IN list is less than + NOT_IN_IGNORE_THRESHOLD, construct the SEL_TREE (*) manually. + * Otherwise, don't produce a SEL_TREE. */ +#define NOT_IN_IGNORE_THRESHOLD 1000 MEM_ROOT *tmp_root= param->mem_root; param->thd->mem_root= param->old_root; /* @@ -3656,9 +3665,9 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, Item *value_item= func->array->create_item(); param->thd->mem_root= tmp_root; - if (!value_item) + if (func->array->count > NOT_IN_IGNORE_THRESHOLD || !value_item) break; - + /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */ uint i=0; do @@ -3677,45 +3686,39 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, tree= NULL; break; } -#define NOT_IN_IGNORE_THRESHOLD 1000 SEL_TREE *tree2; - if (func->array->count < NOT_IN_IGNORE_THRESHOLD) + for (; i < func->array->count; i++) { - for (; i < func->array->count; i++) + if (func->array->compare_elems(i, i-1)) { - if (func->array->compare_elems(i, i-1)) + /* Get a SEL_TREE for "-inf < X < c_i" interval */ + func->array->value_to_item(i, value_item); + tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC, + value_item, cmp_type); + if (!tree2) { - /* Get a SEL_TREE for "-inf < X < c_i" interval */ - func->array->value_to_item(i, value_item); - tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC, - value_item, cmp_type); - if (!tree2) - { - tree= NULL; - break; - } + tree= NULL; + break; + } - /* Change all intervals to be "c_{i-1} < X < c_i" */ - for (uint idx= 0; idx < param->keys; idx++) + /* Change all intervals to be "c_{i-1} < X < c_i" */ + for (uint idx= 0; idx < param->keys; idx++) + { + SEL_ARG *new_interval, *last_val; + if (((new_interval= tree2->keys[idx])) && + ((last_val= tree->keys[idx]->last()))) { - SEL_ARG *new_interval, *last_val; - if (((new_interval= tree2->keys[idx])) && - ((last_val= tree->keys[idx]->last()))) - { - new_interval->min_value= last_val->max_value; - new_interval->min_flag= NEAR_MIN; - } + new_interval->min_value= last_val->max_value; + new_interval->min_flag= NEAR_MIN; } - /* - The following doesn't try to allocate memory so no need to - check for NULL. - */ - tree= tree_or(param, tree, tree2); } + /* + The following doesn't try to allocate memory so no need to + check for NULL. + */ + tree= tree_or(param, tree, tree2); } } - else - func->array->value_to_item(func->array->count - 1, value_item); if (tree && tree->type != SEL_TREE::IMPOSSIBLE) { @@ -3780,7 +3783,118 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, } DBUG_RETURN(tree); +} + +/* + Build conjunction of all SEL_TREEs for a simple predicate applying equalities + + SYNOPSIS + get_full_func_mm_tree() + param PARAM from SQL_SELECT::test_quick_select + cond_func item for the predicate + field_item field in the predicate + value constant in the predicate + (for BETWEEN it contains the number of the field argument, + for IN it's always 0) + inv TRUE <> NOT cond_func is considered + (makes sense only when cond_func is BETWEEN or IN) + + DESCRIPTION + For a simple SARGable predicate of the form (f op c), where f is a field and + c is a constant, the function builds a conjunction of all SEL_TREES that can + be obtained by the substitution of f for all different fields equal to f. + + NOTES + If the WHERE condition contains a predicate (fi op c), + then not only SELL_TREE for this predicate is built, but + the trees for the results of substitution of fi for + each fj belonging to the same multiple equality as fi + are built as well. + E.g. for WHERE t1.a=t2.a AND t2.a > 10 + a SEL_TREE for t2.a > 10 will be built for quick select from t2 + and + a SEL_TREE for t1.a > 10 will be built for quick select from t1. + + A BETWEEN predicate of the form (fi [NOT] BETWEEN c1 AND c2) is treated + in a similar way: we build a conjuction of trees for the results + of all substitutions of fi for equal fj. + Yet a predicate of the form (c BETWEEN f1i AND f2i) is processed + differently. It is considered as a conjuction of two SARGable + predicates (f1i <= c) and (f2i <=c) and the function get_full_func_mm_tree + is called for each of them separately producing trees for + AND j (f1j <=c ) and AND j (f2j <= c) + After this these two trees are united in one conjunctive tree. + It's easy to see that the same tree is obtained for + AND j,k (f1j <=c AND f2k<=c) + which is equivalent to + AND j,k (c BETWEEN f1j AND f2k). + The validity of the processing of the predicate (c NOT BETWEEN f1i AND f2i) + which equivalent to (f1i > c OR f2i < c) is not so obvious. Here the + function get_full_func_mm_tree is called for (f1i > c) and (f2i < c) + producing trees for AND j (f1j > c) and AND j (f2j < c). Then this two + trees are united in one OR-tree. The expression + (AND j (f1j > c) OR AND j (f2j < c) + is equivalent to the expression + AND j,k (f1j > c OR f2k < c) + which is just a translation of + AND j,k (c NOT BETWEEN f1j AND f2k) + + In the cases when one of the items f1, f2 is a constant c1 we do not create + a tree for it at all. It works for BETWEEN predicates but does not + work for NOT BETWEEN predicates as we have to evaluate the expression + with it. If it is TRUE then the other tree can be completely ignored. + We do not do it now and no trees are built in these cases for + NOT BETWEEN predicates. + + As to IN predicates only ones of the form (f IN (c1,...,cn)), + where f1 is a field and c1,...,cn are constant, are considered as + SARGable. We never try to narrow the index scan using predicates of + the form (c IN (c1,...,f,...,cn)). + + RETURN + Pointer to the tree representing the built conjunction of SEL_TREEs +*/ + +static SEL_TREE *get_full_func_mm_tree(PARAM *param, Item_func *cond_func, + Item_field *field_item, Item *value, + bool inv) +{ + SEL_TREE *tree= 0; + SEL_TREE *ftree= 0; + table_map ref_tables= 0; + table_map param_comp= ~(param->prev_tables | param->read_tables | + param->current_table); + DBUG_ENTER("get_full_func_mm_tree"); + + for (uint i= 0; i < cond_func->arg_count; i++) + { + Item *arg= cond_func->arguments()[i]->real_item(); + if (arg != field_item) + ref_tables|= arg->used_tables(); + } + Field *field= field_item->field; + Item_result cmp_type= field->cmp_type(); + if (!((ref_tables | field->table->map) & param_comp)) + ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv); + Item_equal *item_equal= field_item->item_equal; + if (item_equal) + { + Item_equal_iterator it(*item_equal); + Item_field *item; + while ((item= it++)) + { + Field *f= item->field; + if (field->eq(f)) + continue; + if (!((ref_tables | f->table->map) & param_comp)) + { + tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv); + ftree= !ftree ? tree : tree_and(param, ftree, tree); + } + } + } + DBUG_RETURN(ftree); } /* make a select tree of all keys in condition */ @@ -3791,7 +3905,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) SEL_TREE *ftree= 0; Item_field *field_item= 0; bool inv= FALSE; - Item *value; + Item *value= 0; DBUG_ENTER("get_mm_tree"); if (cond->type() == Item::COND_ITEM) @@ -3871,10 +3985,37 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) switch (cond_func->functype()) { case Item_func::BETWEEN: - if (cond_func->arguments()[0]->real_item()->type() != Item::FIELD_ITEM) - DBUG_RETURN(0); - field_item= (Item_field*) (cond_func->arguments()[0]->real_item()); - value= NULL; + if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM) + { + field_item= (Item_field*) (cond_func->arguments()[0]->real_item()); + ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv); + } + + /* + Concerning the code below see the NOTES section in + the comments for the function get_full_func_mm_tree() + */ + for (uint i= 1 ; i < cond_func->arg_count ; i++) + { + + if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM) + { + field_item= (Item_field*) (cond_func->arguments()[i]->real_item()); + SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, + field_item, (Item*) i, inv); + if (inv) + tree= !tree ? tmp : tree_or(param, tree, tmp); + else + tree= tree_and(param, tree, tmp); + } + else if (inv) + { + tree= 0; + break; + } + } + + ftree = tree_and(param, ftree, tree); break; case Item_func::IN_FUNC: { @@ -3882,7 +4023,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) if (func->key_item()->real_item()->type() != Item::FIELD_ITEM) DBUG_RETURN(0); field_item= (Item_field*) (func->key_item()->real_item()); - value= NULL; + ftree= get_full_func_mm_tree(param, cond_func, field_item, NULL, inv); break; } case Item_func::MULT_EQUAL_FUNC: @@ -3921,47 +4062,9 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) } else DBUG_RETURN(0); + ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv); } - /* - If the where condition contains a predicate (ti.field op const), - then not only SELL_TREE for this predicate is built, but - the trees for the results of substitution of ti.field for - each tj.field belonging to the same multiple equality as ti.field - are built as well. - E.g. for WHERE t1.a=t2.a AND t2.a > 10 - a SEL_TREE for t2.a > 10 will be built for quick select from t2 - and - a SEL_TREE for t1.a > 10 will be built for quick select from t1. - */ - - for (uint i= 0; i < cond_func->arg_count; i++) - { - Item *arg= cond_func->arguments()[i]->real_item(); - if (arg != field_item) - ref_tables|= arg->used_tables(); - } - Field *field= field_item->field; - Item_result cmp_type= field->cmp_type(); - if (!((ref_tables | field->table->map) & param_comp)) - ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type, inv); - Item_equal *item_equal= field_item->item_equal; - if (item_equal) - { - Item_equal_iterator it(*item_equal); - Item_field *item; - while ((item= it++)) - { - Field *f= item->field; - if (field->eq(f)) - continue; - if (!((ref_tables | f->table->map) & param_comp)) - { - tree= get_func_mm_tree(param, cond_func, f, value, cmp_type, inv); - ftree= !ftree ? tree : tree_and(param, ftree, tree); - } - } - } DBUG_RETURN(ftree); } @@ -4026,6 +4129,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, MEM_ROOT *alloc= param->mem_root; char *str; ulong orig_sql_mode; + int err; DBUG_ENTER("get_mm_leaf"); /* @@ -4177,7 +4281,13 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, (field->type() == FIELD_TYPE_DATE || field->type() == FIELD_TYPE_DATETIME)) field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES; - if (value->save_in_field_no_warnings(field, 1) < 0) + err= value->save_in_field_no_warnings(field, 1); + if (err > 0 && field->cmp_type() != value->result_type()) + { + tree= 0; + goto end; + } + if (err < 0) { field->table->in_use->variables.sql_mode= orig_sql_mode; /* This happens when we try to insert a NULL field in a not null column */ diff --git a/sql/protocol.cc b/sql/protocol.cc index 650bd8fc58f..5de24ebdcb3 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -53,8 +53,18 @@ bool Protocol_prep::net_store_data(const char *from, uint length) } - /* Send a error string to client */ +/* + Send a error string to client + + Design note: + net_printf_error and net_send_error are low-level functions + that shall be used only when a new connection is being + established or at server startup. + For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's + critical that every error that can be intercepted is issued in one + place only, my_message_sql. +*/ void net_send_error(THD *thd, uint sql_errno, const char *err) { NET *net= &thd->net; @@ -64,19 +74,15 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) err ? err : net->last_error[0] ? net->last_error : "NULL")); + DBUG_ASSERT(!thd->spcont); + if (net && net->no_send_error) { thd->clear_error(); DBUG_PRINT("info", ("sending error messages prohibited")); DBUG_VOID_RETURN; } - if (thd->spcont && thd->spcont->find_handler(sql_errno, - MYSQL_ERROR::WARN_LEVEL_ERROR)) - { - if (! thd->spcont->found_handler_here()) - thd->net.report_error= 1; /* Make "select" abort correctly */ - DBUG_VOID_RETURN; - } + thd->query_error= 1; // needed to catch query errors during replication if (!err) { @@ -117,6 +123,15 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) Write error package and flush to client It's a little too low level, but I don't want to use another buffer for this + + Design note: + + net_printf_error and net_send_error are low-level functions + that shall be used only when a new connection is being + established or at server startup. + For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's + critical that every error that can be intercepted is issued in one + place only, my_message_sql. */ void @@ -136,6 +151,8 @@ net_printf_error(THD *thd, uint errcode, ...) DBUG_ENTER("net_printf_error"); DBUG_PRINT("enter",("message: %u",errcode)); + DBUG_ASSERT(!thd->spcont); + if (net && net->no_send_error) { thd->clear_error(); @@ -143,13 +160,6 @@ net_printf_error(THD *thd, uint errcode, ...) DBUG_VOID_RETURN; } - if (thd->spcont && thd->spcont->find_handler(errcode, - MYSQL_ERROR::WARN_LEVEL_ERROR)) - { - if (! thd->spcont->found_handler_here()) - thd->net.report_error= 1; /* Make "select" abort correctly */ - DBUG_VOID_RETURN; - } thd->query_error= 1; // needed to catch query errors during replication #ifndef EMBEDDED_LIBRARY query_cache_abort(net); // Safety @@ -322,7 +332,7 @@ static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */ 254 Marker (1 byte) warning_count Stored in 2 bytes; New in 4.1 protocol status_flag Stored in 2 bytes; - For flags like SERVER_STATUS_MORE_RESULTS + For flags like SERVER_MORE_RESULTS_EXISTS Note that the warning count will not be sent if 'no_flush' is set as we don't want to report the warning count until all data is sent to the diff --git a/sql/set_var.cc b/sql/set_var.cc index 9f3886bca4d..c667e2f2bcc 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -509,7 +509,8 @@ static sys_var_thd_bit sys_sql_big_tables("sql_big_tables", 0, static sys_var_thd_bit sys_big_selects("sql_big_selects", 0, set_option_bit, OPTION_BIG_SELECTS); -static sys_var_thd_bit sys_log_off("sql_log_off", 0, +static sys_var_thd_bit sys_log_off("sql_log_off", + check_log_update, set_option_bit, OPTION_LOG_OFF); static sys_var_thd_bit sys_log_update("sql_log_update", @@ -869,8 +870,8 @@ struct show_var_st init_vars[]= { {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, - {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE}, {"have_merge_engine", (char*) &have_merge_db, SHOW_HAVE}, + {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE}, {"have_openssl", (char*) &have_openssl, SHOW_HAVE}, {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE}, {"have_raid", (char*) &have_raid, SHOW_HAVE}, @@ -3251,7 +3252,7 @@ int set_var_user::check(THD *thd) 0 can be passed as last argument (reference on item) */ return (user_var_item->fix_fields(thd, (Item**) 0) || - user_var_item->check()) ? -1 : 0; + user_var_item->check(0)) ? -1 : 0; } diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 5c967ba19bd..d10f66e3878 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -54,7 +54,7 @@ ER_CANT_CREATE_FILE cze "Nemohu vytvo-Bøit soubor '%-.64s' (chybový kód: %d)" dan "Kan ikke oprette filen '%-.64s' (Fejlkode: %d)" nla "Kan file '%-.64s' niet aanmaken (Errcode: %d)" - eng "Can't create file '%-.64s' (errno: %d)" + eng "Can't create file '%-.200s' (errno: %d)" est "Ei suuda luua faili '%-.64s' (veakood: %d)" fre "Ne peut créer le fichier '%-.64s' (Errcode: %d)" ger "Kann Datei '%-.64s' nicht erzeugen (Fehler: %d)" @@ -278,7 +278,7 @@ ER_CANT_GET_STAT cze "Nemohu z-Bískat stav '%-.64s' (chybový kód: %d)" dan "Kan ikke læse status af '%-.64s' (Fejlkode: %d)" nla "Kan de status niet krijgen van '%-.64s' (Errcode: %d)" - eng "Can't get status of '%-.64s' (errno: %d)" + eng "Can't get status of '%-.200s' (errno: %d)" jps "'%-.64s' ‚̃XƒeƒCƒ^ƒX‚ª“¾‚ç‚ê‚Ü‚¹‚ñ. (errno: %d)", est "Ei suuda lugeda '%-.64s' olekut (veakood: %d)" fre "Ne peut obtenir le status de '%-.64s' (Errcode: %d)" @@ -353,7 +353,7 @@ ER_CANT_OPEN_FILE cze "Nemohu otev-Bøít soubor '%-.64s' (chybový kód: %d)" dan "Kan ikke åbne fil: '%-.64s' (Fejlkode: %d)" nla "Kan de file '%-.64s' niet openen (Errcode: %d)" - eng "Can't open file: '%-.64s' (errno: %d)" + eng "Can't open file: '%-.200s' (errno: %d)" jps "'%-.64s' ƒtƒ@ƒCƒ‹‚ðŠJ‚Ž–‚ª‚Å‚«‚Ü‚¹‚ñ (errno: %d)", est "Ei suuda avada faili '%-.64s' (veakood: %d)" fre "Ne peut ouvrir le fichier: '%-.64s' (Errcode: %d)" @@ -378,7 +378,7 @@ ER_FILE_NOT_FOUND cze "Nemohu naj-Bít soubor '%-.64s' (chybový kód: %d)" dan "Kan ikke finde fila: '%-.64s' (Fejlkode: %d)" nla "Kan de file: '%-.64s' niet vinden (Errcode: %d)" - eng "Can't find file: '%-.64s' (errno: %d)" + eng "Can't find file: '%-.200s' (errno: %d)" jps "'%-.64s' ƒtƒ@ƒCƒ‹‚ðŒ©•t‚¯‚鎖‚ª‚Å‚«‚Ü‚¹‚ñ.(errno: %d)", est "Ei suuda leida faili '%-.64s' (veakood: %d)" fre "Ne peut trouver le fichier: '%-.64s' (Errcode: %d)" @@ -549,7 +549,7 @@ ER_ERROR_ON_READ cze "Chyba p-Bøi ètení souboru '%-.64s' (chybový kód: %d)" dan "Fejl ved læsning af '%-.64s' (Fejlkode: %d)" nla "Fout bij het lezen van file '%-.64s' (Errcode: %d)" - eng "Error reading file '%-.64s' (errno: %d)" + eng "Error reading file '%-.200s' (errno: %d)" jps "'%-.64s' ƒtƒ@ƒCƒ‹‚Ì“Ç‚Ýž‚݃Gƒ‰[ (errno: %d)", est "Viga faili '%-.64s' lugemisel (veakood: %d)" fre "Erreur en lecture du fichier '%-.64s' (Errcode: %d)" @@ -599,7 +599,7 @@ ER_ERROR_ON_WRITE cze "Chyba p-Bøi zápisu do souboru '%-.64s' (chybový kód: %d)" dan "Fejl ved skriving av filen '%-.64s' (Fejlkode: %d)" nla "Fout bij het wegschrijven van file '%-.64s' (Errcode: %d)" - eng "Error writing file '%-.64s' (errno: %d)" + eng "Error writing file '%-.200s' (errno: %d)" jps "'%-.64s' ƒtƒ@ƒCƒ‹‚ð‘‚Ž–‚ª‚Å‚«‚Ü‚¹‚ñ (errno: %d)", est "Viga faili '%-.64s' kirjutamisel (veakood: %d)" fre "Erreur d'écriture du fichier '%-.64s' (Errcode: %d)" @@ -772,7 +772,7 @@ ER_NOT_FORM_FILE cze "Nespr-Bávná informace v souboru '%-.64s'" dan "Forkert indhold i: '%-.64s'" nla "Verkeerde info in file: '%-.64s'" - eng "Incorrect information in file: '%-.64s'" + eng "Incorrect information in file: '%-.200s'" jps "ƒtƒ@ƒCƒ‹ '%-.64s' ‚Ì info ‚ªŠÔˆá‚Á‚Ä‚¢‚é‚悤‚Å‚·", est "Vigane informatsioon failis '%-.64s'" fre "Information erronnée dans le fichier: '%-.64s'" @@ -797,7 +797,7 @@ ER_NOT_KEYFILE cze "Nespr-Bávný klíè pro tabulku '%-.64s'; pokuste se ho opravit" dan "Fejl i indeksfilen til tabellen '%-.64s'; prøv at reparere den" nla "Verkeerde zoeksleutel file voor tabel: '%-.64s'; probeer het te repareren" - eng "Incorrect key file for table '%-.64s'; try to repair it" + eng "Incorrect key file for table '%-.200s'; try to repair it" jps "'%-.64s' ƒe[ƒuƒ‹‚Ì key file ‚ªŠÔˆá‚Á‚Ä‚¢‚é‚悤‚Å‚·. C•œ‚ð‚µ‚Ä‚‚¾‚³‚¢", est "Tabeli '%-.64s' võtmefail on vigane; proovi seda parandada" fre "Index corrompu dans la table: '%-.64s'; essayez de le réparer" @@ -2044,7 +2044,7 @@ ER_TEXTFILE_NOT_READABLE cze "Soubor '%-.64s' mus-Bí být v adresáøi databáze nebo èitelný pro v¹echny" dan "Filen '%-.64s' skal være i database-folderen og kunne læses af alle" nla "Het bestand '%-.64s' dient in de database directory voor the komen of leesbaar voor iedereen te zijn." - eng "The file '%-.64s' must be in the database directory or be readable by all" + eng "The file '%-.128s' must be in the database directory or be readable by all" jps "ƒtƒ@ƒCƒ‹ '%-.64s' ‚Í databse ‚Ì directory ‚É‚ ‚é‚©‘S‚Ẵ†[ƒU[‚ª“Ç‚ß‚é‚悤‚É‹–‰Â‚³‚ê‚Ä‚¢‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñ.", est "Fail '%-.64s' peab asuma andmebaasi kataloogis või olema kõigile loetav" fre "Le fichier '%-.64s' doit être dans le répertoire de la base et lisible par tous" @@ -2069,7 +2069,7 @@ ER_FILE_EXISTS_ERROR cze "Soubor '%-.64s' ji-B¾ existuje" dan "Filen '%-.64s' eksisterer allerede" nla "Het bestand '%-.64s' bestaat reeds" - eng "File '%-.80s' already exists" + eng "File '%-.200s' already exists" jps "File '%-.64s' ‚ÍŠù‚É‘¶Ý‚µ‚Ü‚·", est "Fail '%-.80s' juba eksisteerib" fre "Le fichier '%-.64s' existe déjà" @@ -2345,7 +2345,7 @@ ER_NO_UNIQUE_LOGFILE cze "Nemohu vytvo-Bøit jednoznaèné jméno logovacího souboru %s.(1-999)\n" dan "Kan ikke lave unikt log-filnavn %s.(1-999)\n" nla "Het is niet mogelijk een unieke naam te maken voor de logfile %s.(1-999)\n" - eng "Can't generate a unique log-filename %-.64s.(1-999)\n" + eng "Can't generate a unique log-filename %-.200s.(1-999)\n" est "Ei suuda luua unikaalset logifaili nime %-.64s.(1-999)\n" fre "Ne peut générer un unique nom de journal %s.(1-999)\n" ger "Kann keinen eindeutigen Dateinamen für die Logdatei %-.64s(1-999) erzeugen\n" @@ -4893,8 +4893,8 @@ ER_WARN_TOO_MANY_RECORDS 01000 por "Conta de registro é maior que a conta de coluna na linha %ld" spa "Línea %ld fué truncada; La misma contine mas datos que las que existen en las columnas de entrada" ER_WARN_NULL_TO_NOTNULL 22004 - eng "Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld" - ger "Feld auf Vorgabewert gesetzt, da NULL für NOT-NULL-Feld '%s' in Zeile %ld angegeben" + eng "Column was set to data type implicit default; NULL supplied for NOT NULL column '%s' at row %ld" + ger "Feld auf Datentyp-spezifischen Vorgabewert gesetzt; da NULL für NOT-NULL-Feld '%s' in Zeile %ld angegeben" por "Dado truncado, NULL fornecido para NOT NULL coluna '%s' na linha %ld" spa "Datos truncado, NULL suministrado para NOT NULL columna '%s' en la línea %ld" ER_WARN_DATA_OUT_OF_RANGE 22003 @@ -5218,7 +5218,7 @@ ER_FPARSER_BAD_HEADER rus "îÅ×ÅÒÎÙÊ ÚÁÇÏÌÏ×ÏË ÔÉÐÁ ÆÁÊÌÁ '%-.64s'" ukr "îÅצÒÎÉÊ ÚÁÇÏÌÏ×ÏË ÔÉÐÕ Õ ÆÁÊ̦ '%-.64s'" ER_FPARSER_EOF_IN_COMMENT - eng "Unexpected end of file while parsing comment '%-.64s'" + eng "Unexpected end of file while parsing comment '%-.200s'" ger "Unerwartetes Dateiende beim Parsen des Kommentars '%-.64s'" rus "îÅÏÖÉÄÁÎÎÙÊ ËÏÎÅà ÆÁÊÌÁ × ËÏÍÅÎÔÁÒÉÉ '%-.64s'" ukr "îÅÓÐÏĦ×ÁÎÎÉÊ Ë¦ÎÅÃØ ÆÁÊÌÕ Õ ËÏÍÅÎÔÁÒ¦ '%-.64s'" @@ -5387,7 +5387,7 @@ ER_LOGGING_PROHIBIT_CHANGING_OF eng "Binary logging and replication forbid changing the global server %s" ger "Binärlogs und Replikation verhindern Wechsel des globalen Servers %s" ER_NO_FILE_MAPPING - eng "Can't map file: %-.64s, errno: %d" + eng "Can't map file: %-.200s, errno: %d" ger "Kann Datei nicht abbilden: %-.64s, Fehler: %d" ER_WRONG_MAGIC eng "Wrong magic in %-.64s" @@ -5623,3 +5623,9 @@ ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA eng "Triggers can not be created on system tables" ER_REMOVED_SPACES eng "Leading spaces are removed from name '%s'" +ER_USERNAME + eng "user name" +ER_HOSTNAME + eng "host name" +ER_WRONG_STRING_LENGTH + eng "String '%-.70s' is too long for %s (should be no longer than %d)" diff --git a/sql/slave.cc b/sql/slave.cc index 90e95e812bd..55cff94a179 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3051,7 +3051,7 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings) return packet_error; #endif - len = net_safe_read(mysql); + len = cli_safe_read(mysql); if (len == packet_error || (long) len < 1) { if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED) @@ -3226,7 +3226,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) rli->is_until_satisfied()) { char buf[22]; - sql_print_error("Slave SQL thread stopped because it reached its" + sql_print_information("Slave SQL thread stopped because it reached its" " UNTIL position %s", llstr(rli->until_pos(), buf)); /* Setting abort_slave flag because we do not want additional message about diff --git a/sql/slave.h b/sql/slave.h index c355f7172a9..dee134aaa0c 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -406,7 +406,7 @@ typedef struct st_master_info /* the variables below are needed because we can change masters on the fly */ char master_log_name[FN_REFLEN]; char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_LENGTH+1]; + char user[USERNAME_BYTE_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; my_bool ssl; // enables use of SSL connection if true char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; diff --git a/sql/sp.cc b/sql/sp.cc index a7078da2f50..63175b110fa 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -404,16 +404,16 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, { LEX *old_lex= thd->lex, newlex; String defstr; - char old_db_buf[NAME_LEN+1]; + char old_db_buf[NAME_BYTE_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; ulong old_sql_mode= thd->variables.sql_mode; ha_rows old_select_limit= thd->variables.select_limit; sp_rcontext *old_spcont= thd->spcont; - char definer_user_name_holder[USERNAME_LENGTH + 1]; + char definer_user_name_holder[USERNAME_BYTE_LENGTH + 1]; LEX_STRING_WITH_INIT definer_user_name(definer_user_name_holder, - USERNAME_LENGTH); + USERNAME_BYTE_LENGTH); char definer_host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING_WITH_INIT definer_host_name(definer_host_name_holder, @@ -495,6 +495,13 @@ sp_returns_type(THD *thd, String &result, sp_head *sp) table.s = &table.share_not_to_be_used; field= sp->create_result_field(0, 0, &table); field->sql_type(result); + + if (field->has_charset()) + { + result.append(STRING_WITH_LEN(" CHARSET ")); + result.append(field->charset()->csname); + } + delete field; } @@ -504,7 +511,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) int ret; TABLE *table; char definer[USER_HOST_BUFF_SIZE]; - char old_db_buf[NAME_LEN+1]; + char old_db_buf[NAME_BYTE_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; DBUG_ENTER("db_create_routine"); @@ -626,7 +633,10 @@ db_create_routine(THD *thd, int type, sp_head *sp) log_query.append(STRING_WITH_LEN("CREATE ")); append_definer(thd, &log_query, &thd->lex->definer->user, &thd->lex->definer->host); - log_query.append(thd->lex->stmt_definition_begin); + log_query.append(thd->lex->stmt_definition_begin, + (char *)sp->m_body_begin - + thd->lex->stmt_definition_begin + + sp->m_body.length); /* Such a statement can always go directly to binlog, no trans cache */ Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0, @@ -974,6 +984,11 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, sp_head *new_sp; const char *returns= ""; char definer[USER_HOST_BUFF_SIZE]; + + /* + String buffer for RETURNS data type must have system charset; + 64 -- size of "returns" column of mysql.proc. + */ String retstr(64); DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp)); @@ -991,6 +1006,12 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, } DBUG_RETURN(sp->m_first_free_instance); } + /* + Actually depth could be +1 than the actual value in case a SP calls + SHOW CREATE PROCEDURE. Hence, the linked list could hold up to one more + instance. + */ + level= sp->m_last_cached_sp->m_recursion_level + 1; if (level > depth) { @@ -1160,19 +1181,22 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics) int sp_show_create_procedure(THD *thd, sp_name *name) { + int ret= SP_KEY_NOT_FOUND; sp_head *sp; DBUG_ENTER("sp_show_create_procedure"); DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); + /* + Increase the recursion limit for this statement. SHOW CREATE PROCEDURE + does not do actual recursion. + */ + thd->variables.max_sp_recursion_depth++; if ((sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name, &thd->sp_proc_cache, FALSE))) - { - int ret= sp->show_create_procedure(thd); + ret= sp->show_create_procedure(thd); - DBUG_RETURN(ret); - } - - DBUG_RETURN(SP_KEY_NOT_FOUND); + thd->variables.max_sp_recursion_depth--; + DBUG_RETURN(ret); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 9965c48935a..e5b0b1e606e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -230,6 +230,12 @@ sp_get_flags_for_command(LEX *lex) else flags= sp_head::HAS_COMMIT_OR_ROLLBACK; break; + case SQLCOM_FLUSH: + flags= sp_head::HAS_SQLCOM_FLUSH; + break; + case SQLCOM_RESET: + flags= sp_head::HAS_SQLCOM_RESET; + break; case SQLCOM_CREATE_INDEX: case SQLCOM_CREATE_DB: case SQLCOM_CREATE_VIEW: @@ -470,7 +476,7 @@ sp_head::init(LEX *lex) lex->trg_table_fields.empty(); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_param_begin= m_param_end= m_body_begin= 0; - m_qname.str= m_db.str= m_name.str= m_params.str= + m_qname.str= m_db.str= m_name.str= m_params.str= m_body.str= m_defstr.str= 0; m_qname.length= m_db.length= m_name.length= m_params.length= m_body.length= m_defstr.length= 0; @@ -478,29 +484,42 @@ sp_head::init(LEX *lex) DBUG_VOID_RETURN; } + +void +sp_head::init_sp_name(THD *thd, sp_name *spname) +{ + DBUG_ENTER("sp_head::init_sp_name"); + + /* Must be initialized in the parser. */ + + DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length); + + /* We have to copy strings to get them into the right memroot. */ + + m_db.length= spname->m_db.length; + m_db.str= strmake_root(thd->mem_root, spname->m_db.str, spname->m_db.length); + + m_name.length= spname->m_name.length; + m_name.str= strmake_root(thd->mem_root, spname->m_name.str, + spname->m_name.length); + + if (spname->m_qname.length == 0) + spname->init_qname(thd); + + m_qname.length= spname->m_qname.length; + m_qname.str= strmake_root(thd->mem_root, spname->m_qname.str, + m_qname.length); +} + + void -sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) +sp_head::init_strings(THD *thd, LEX *lex) { DBUG_ENTER("sp_head::init_strings"); uchar *endp; /* Used to trim the end */ /* During parsing, we must use thd->mem_root */ MEM_ROOT *root= thd->mem_root; - DBUG_ASSERT(name); - /* Must be initialized in the parser */ - DBUG_ASSERT(name->m_db.str && name->m_db.length); - - /* We have to copy strings to get them into the right memroot */ - m_db.length= name->m_db.length; - m_db.str= strmake_root(root, name->m_db.str, name->m_db.length); - m_name.length= name->m_name.length; - m_name.str= strmake_root(root, name->m_name.str, name->m_name.length); - - if (name->m_qname.length == 0) - name->init_qname(thd); - m_qname.length= name->m_qname.length; - m_qname.str= strmake_root(root, name->m_qname.str, m_qname.length); - if (m_param_begin && m_param_end) { m_params.length= m_param_end - m_param_begin; @@ -514,10 +533,7 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) Trim "garbage" at the end. This is sometimes needed with the "/ * ! VERSION... * /" wrapper in dump files. */ - while (m_body_begin < endp && - (endp[-1] <= ' ' || endp[-1] == '*' || - endp[-1] == '/' || endp[-1] == ';')) - endp-= 1; + endp= skip_rear_comments(m_body_begin, endp); m_body.length= endp - m_body_begin; m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length); @@ -908,7 +924,7 @@ bool sp_head::execute(THD *thd) { DBUG_ENTER("sp_head::execute"); - char old_db_buf[NAME_LEN+1]; + char old_db_buf[NAME_BYTE_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; sp_rcontext *ctx; @@ -1097,6 +1113,7 @@ sp_head::execute(THD *thd) thd->restore_active_arena(&execute_arena, &backup_arena); + thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error /* Restore all saved */ old_packet.swap(thd->packet); @@ -1158,6 +1175,161 @@ sp_head::execute(THD *thd) m_first_instance->m_first_free_instance->m_recursion_level == m_recursion_level + 1)); m_first_instance->m_first_free_instance= this; + + DBUG_RETURN(err_status); +} + + +#ifndef NO_EMBEDDED_ACCESS_CHECKS +/* + set_routine_security_ctx() changes routine security context, and + checks if there is an EXECUTE privilege in new context. If there is + no EXECUTE privilege, it changes the context back and returns a + error. + + SYNOPSIS + set_routine_security_ctx() + thd thread handle + sp stored routine to change the context for + is_proc TRUE is procedure, FALSE if function + save_ctx pointer to an old security context + + RETURN + TRUE if there was a error, and the context wasn't changed. + FALSE if the context was changed. +*/ + +bool +set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, + Security_context **save_ctx) +{ + *save_ctx= 0; + if (sp_change_security_context(thd, sp, save_ctx)) + return TRUE; + + /* + If we changed context to run as another user, we need to check the + access right for the new context again as someone may have revoked + the right to use the procedure from this user. + + TODO: + Cache if the definer has the right to use the object on the + first usage and only reset the cache if someone does a GRANT + statement that 'may' affect this. + */ + if (*save_ctx && + check_routine_access(thd, EXECUTE_ACL, + sp->m_db.str, sp->m_name.str, is_proc, FALSE)) + { + sp_restore_security_context(thd, *save_ctx); + *save_ctx= 0; + return TRUE; + } + + return FALSE; +} +#endif // ! NO_EMBEDDED_ACCESS_CHECKS + + +/* + Execute a trigger: + - changes security context for triggers + - switch to new memroot + - call sp_head::execute + - restore old memroot + - restores security context + + SYNOPSIS + sp_head::execute_trigger() + thd Thread handle + db database name + table table name + grant_info GRANT_INFO structure to be filled with + information about definer's privileges + on subject table + + RETURN + FALSE on success + TRUE on error +*/ + +bool +sp_head::execute_trigger(THD *thd, const char *db, const char *table, + GRANT_INFO *grant_info) +{ + sp_rcontext *octx = thd->spcont; + sp_rcontext *nctx = NULL; + bool err_status= FALSE; + MEM_ROOT call_mem_root; + Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); + Query_arena backup_arena; + + DBUG_ENTER("sp_head::execute_trigger"); + DBUG_PRINT("info", ("trigger %s", m_name.str)); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_ctx; + if (sp_change_security_context(thd, this, &save_ctx)) + DBUG_RETURN(TRUE); + + /* + NOTE: TRIGGER_ACL should be used here. + */ + if (check_global_access(thd, SUPER_ACL)) + { + sp_restore_security_context(thd, save_ctx); + DBUG_RETURN(TRUE); + } + + /* + Fetch information about table-level privileges to GRANT_INFO + structure for subject table. Check of privileges that will use it + and information about column-level privileges will happen in + Item_trigger_field::fix_fields(). + */ + fill_effective_table_privileges(thd, grant_info, db, table); +#endif // NO_EMBEDDED_ACCESS_CHECKS + + /* + Prepare arena and memroot for objects which lifetime is whole + duration of trigger call (sp_rcontext, it's tables and items, + sp_cursor and Item_cache holders for case expressions). We can't + use caller's arena/memroot for those objects because in this case + some fixed amount of memory will be consumed for each trigger + invocation and so statements which involve lot of them will hog + memory. + + TODO: we should create sp_rcontext once per command and reuse it + on subsequent executions of a trigger. + */ + init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + thd->set_n_backup_active_arena(&call_arena, &backup_arena); + + if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) || + nctx->init(thd)) + { + err_status= TRUE; + goto err_with_cleanup; + } + +#ifndef DBUG_OFF + nctx->sp= this; +#endif + + thd->spcont= nctx; + + err_status= execute(thd); + +err_with_cleanup: + thd->restore_active_arena(&call_arena, &backup_arena); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + sp_restore_security_context(thd, save_ctx); +#endif // NO_EMBEDDED_ACCESS_CHECKS + delete nctx; + call_arena.free_items(); + free_root(&call_mem_root, MYF(0)); + thd->spcont= octx; + DBUG_RETURN(err_status); } @@ -1165,8 +1337,12 @@ sp_head::execute(THD *thd) /* Execute a function: - evaluate parameters + - changes security context for SUID routines + - switch to new memroot - call sp_head::execute + - restore old memroot - evaluate the return value + - restores security context SYNOPSIS sp_head::execute_function() @@ -1293,6 +1469,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, } thd->spcont= nctx; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_security_ctx; + if (set_routine_security_ctx(thd, this, FALSE, &save_security_ctx)) + { + err_status= TRUE; + goto err_with_cleanup; + } +#endif + binlog_save_options= thd->options; if (need_binlog_call) { @@ -1333,7 +1518,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, reset_dynamic(&thd->user_var_events); } - if (m_type == TYPE_ENUM_FUNCTION && !err_status) + if (!err_status) { /* We need result only in function but not in trigger */ @@ -1344,8 +1529,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, } } - - nctx->pop_all_cursors(); // To avoid memory leaks after an error +#ifndef NO_EMBEDDED_ACCESS_CHECKS + sp_restore_security_context(thd, save_security_ctx); +#endif err_with_cleanup: delete nctx; @@ -1368,8 +1554,10 @@ err_with_cleanup: The function does the following steps: - Set all parameters + - changes security context for SUID routines - call sp_head::execute - copy back values of INOUT and OUT parameters + - restores security context RETURN FALSE on success @@ -1490,6 +1678,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) thd->spcont= nctx; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_security_ctx= 0; + if (!err_status) + err_status= set_routine_security_ctx(thd, this, TRUE, &save_security_ctx); +#endif + if (!err_status) err_status= execute(thd); @@ -1534,10 +1728,14 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } } +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (save_security_ctx) + sp_restore_security_context(thd, save_security_ctx); +#endif + if (!save_spcont) delete octx; - nctx->pop_all_cursors(); // To avoid memory leaks after an error delete nctx; thd->spcont= save_spcont; @@ -1674,14 +1872,18 @@ sp_head::fill_field_definition(THD *thd, LEX *lex, enum enum_field_types field_type, create_field *field_def) { + HA_CREATE_INFO sp_db_info; LEX_STRING cmt = { 0, 0 }; uint unused1= 0; int unused2= 0; + load_db_opt_by_name(thd, m_db.str, &sp_db_info); + if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec, lex->type, (Item*) 0, (Item*) 0, &cmt, 0, &lex->interval_list, - (lex->charset ? lex->charset : default_charset_info), + (lex->charset ? lex->charset : + sp_db_info.default_table_charset), lex->uint_geom_type)) return TRUE; @@ -1755,8 +1957,8 @@ sp_head::set_info(longlong created, longlong modified, void sp_head::set_definer(const char *definer, uint definerlen) { - char user_name_holder[USERNAME_LENGTH + 1]; - LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_LENGTH); + char user_name_holder[USERNAME_BYTE_LENGTH + 1]; + LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_BYTE_LENGTH); char host_name_holder[HOSTNAME_LENGTH + 1]; LEX_STRING_WITH_INIT host_name(host_name_holder, HOSTNAME_LENGTH); diff --git a/sql/sp_head.h b/sql/sp_head.h index 073cca2cd12..7f2da69aa0c 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -115,7 +115,9 @@ public: IS_INVOKED= 32, // Is set if this sp_head is being used HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit' /* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */ - HAS_COMMIT_OR_ROLLBACK= 128 + HAS_COMMIT_OR_ROLLBACK= 128, + HAS_SQLCOM_RESET= 2048, + HAS_SQLCOM_FLUSH= 4096 }; /* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */ @@ -193,9 +195,13 @@ public: void init(LEX *lex); + /* Copy sp name from parser. */ + void + init_sp_name(THD *thd, sp_name *spname); + // Initialize strings after parsing header void - init_strings(THD *thd, LEX *lex, sp_name *name); + init_strings(THD *thd, LEX *lex); int create(THD *thd); @@ -207,6 +213,10 @@ public: destroy(); bool + execute_trigger(THD *thd, const char *db, const char *table, + GRANT_INFO *grant_onfo); + + bool execute_function(THD *thd, Item **args, uint argcount, Field *return_fld); bool @@ -327,14 +337,16 @@ public: my_error(ER_SP_NO_RETSET, MYF(0), where); else if (m_flags & HAS_SET_AUTOCOMMIT_STMT) my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0)); - else if (m_type != TYPE_ENUM_PROCEDURE && - (m_flags & sp_head::HAS_COMMIT_OR_ROLLBACK)) - { + else if (m_flags & HAS_COMMIT_OR_ROLLBACK) my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0)); - return TRUE; - } + else if (m_flags & HAS_SQLCOM_RESET) + my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "RESET"); + else if (m_flags & HAS_SQLCOM_FLUSH) + my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH"); + return test(m_flags & - (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT)); + (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT| + HAS_COMMIT_OR_ROLLBACK|HAS_SQLCOM_RESET|HAS_SQLCOM_FLUSH)); } #ifndef DBUG_OFF @@ -1149,6 +1161,10 @@ sp_change_security_context(THD *thd, sp_head *sp, Security_context **backup); void sp_restore_security_context(THD *thd, Security_context *backup); + +bool +set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, + Security_context **save_ctx); #endif /* NO_EMBEDDED_ACCESS_CHECKS */ TABLE_LIST * diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 3bc27a029d0..67ee5459bb4 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -260,6 +260,65 @@ sp_rcontext::find_handler(uint sql_errno, return TRUE; } +/* + Handle the error for a given errno. + The severity of the error is adjusted depending of the current sql_mode. + If an handler is present for the error (see find_handler()), + this function will return true. + If a handler is found and if the severity of the error indicate + that the current instruction executed should abort, + the flag thd->net.report_error is also set. + This will cause the execution of the current instruction in a + sp_instr* to fail, and give control to the handler code itself + in the sp_head::execute() loop. + + SYNOPSIS + sql_errno The error code + level Warning level + thd The current thread + - thd->net.report_error is an optional output. + + RETURN + TRUE if a handler was found. + FALSE if no handler was found. +*/ +bool +sp_rcontext::handle_error(uint sql_errno, + MYSQL_ERROR::enum_warning_level level, + THD *thd) +{ + bool handled= FALSE; + MYSQL_ERROR::enum_warning_level elevated_level= level; + + + /* Depending on the sql_mode of execution, + warnings may be considered errors */ + if ((level == MYSQL_ERROR::WARN_LEVEL_WARN) && + thd->really_abort_on_warning()) + { + elevated_level= MYSQL_ERROR::WARN_LEVEL_ERROR; + } + + if (find_handler(sql_errno, elevated_level)) + { + if (elevated_level == MYSQL_ERROR::WARN_LEVEL_ERROR) + { + /* + Forces to abort the current instruction execution. + NOTE: This code is altering the original meaning of + the net.report_error flag (send an error to the client). + In the context of stored procedures with error handlers, + the flag is reused to cause error propagation, + until the error handler is reached. + No messages will be sent to the client in that context. + */ + thd->net.report_error= 1; + } + handled= TRUE; + } + + return handled; +} void sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 30521f6da84..5e03aa60d23 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -128,6 +128,12 @@ class sp_rcontext : public Sql_alloc bool find_handler(uint sql_errno,MYSQL_ERROR::enum_warning_level level); + // If there is an error handler for this error, handle it and return TRUE. + bool + handle_error(uint sql_errno, + MYSQL_ERROR::enum_warning_level level, + THD *thd); + // Returns handler type and sets *ip to location if one was found inline int found_handler(uint *ip, uint *fp) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ae5ea210a47..010a5c33b96 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -54,7 +54,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length, } #define IP_ADDR_STRLEN (3+1+3+1+3+1+3) -#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1) +#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_BYTE_LEN+1+USERNAME_BYTE_LENGTH+1) static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs; static MEM_ROOT mem, memex; @@ -197,7 +197,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) READ_RECORD read_record_info; my_bool return_val= 1; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; - char tmp_name[NAME_LEN+1]; + char tmp_name[NAME_BYTE_LEN+1]; int password_length; DBUG_ENTER("acl_load"); @@ -874,6 +874,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, sql_print_information("X509 issuer mismatch: should be '%s' " "but is '%s'", acl_user->x509_issuer, ptr); free(ptr); + user_access=NO_ACCESS; break; } user_access= acl_user->access; @@ -889,11 +890,13 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, if (strcmp(acl_user->x509_subject,ptr)) { if (global_system_variables.log_warnings) - sql_print_information("X509 subject mismatch: '%s' vs '%s'", + sql_print_information("X509 subject mismatch: should be '%s' but is '%s'", acl_user->x509_subject, ptr); + free(ptr); + user_access=NO_ACCESS; + break; } - else - user_access= acl_user->access; + user_access= acl_user->access; free(ptr); } break; @@ -2261,7 +2264,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash, const char *user, const char *tname, bool exact) { - char helping [NAME_LEN*2+USERNAME_LENGTH+3]; + char helping [NAME_BYTE_LEN*2+USERNAME_BYTE_LENGTH+3]; uint len; GRANT_NAME *grant_name,*found=0; HASH_SEARCH_STATE state; @@ -2900,14 +2903,6 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, result= TRUE; continue; } - if (Str->host.length > HOSTNAME_LENGTH || - Str->user.length > USERNAME_LENGTH) - { - my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), - MYF(0)); - result= TRUE; - continue; - } /* Create user if needed */ error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users, @@ -3112,15 +3107,6 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, result= TRUE; continue; } - if (Str->host.length > HOSTNAME_LENGTH || - Str->user.length > USERNAME_LENGTH) - { - if (!no_error) - my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), - MYF(0)); - result= TRUE; - continue; - } /* Create user if needed */ error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users, @@ -3181,7 +3167,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, { List_iterator <LEX_USER> str_list (list); LEX_USER *Str, *tmp_Str; - char tmp_db[NAME_LEN+1]; + char tmp_db[NAME_BYTE_LEN+1]; bool create_new_users=0; TABLE_LIST tables[2]; DBUG_ENTER("mysql_grant"); @@ -3246,14 +3232,6 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, result= TRUE; continue; } - if (Str->host.length > HOSTNAME_LENGTH || - Str->user.length > USERNAME_LENGTH) - { - my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), - MYF(0)); - result= -1; - continue; - } if (replace_user_table(thd, tables[0].table, *Str, (!db ? rights : 0), revoke_grant, create_new_users, test(thd->variables.sql_mode & @@ -3787,9 +3765,24 @@ bool check_column_grant_in_table_ref(THD *thd, TABLE_LIST * table_ref, if (table_ref->view || table_ref->field_translation) { /* View or derived information schema table. */ + ulong view_privs; grant= &(table_ref->grant); db_name= table_ref->view_db.str; table_name= table_ref->view_name.str; + if (table_ref->belong_to_view && + (thd->lex->sql_command == SQLCOM_SHOW_FIELDS || + thd->lex->sql_command == SQLCOM_SHOW_CREATE)) + { + view_privs= get_column_grant(thd, grant, db_name, table_name, name); + if (view_privs & VIEW_ANY_ACL) + { + table_ref->belong_to_view->allowed_show= TRUE; + return FALSE; + } + table_ref->belong_to_view->allowed_show= FALSE; + my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0)); + return TRUE; + } } else { @@ -3874,7 +3867,7 @@ err2: bool check_grant_db(THD *thd,const char *db) { Security_context *sctx= thd->security_ctx; - char helping [NAME_LEN+USERNAME_LENGTH+2]; + char helping [NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+2]; uint len; bool error= 1; @@ -4144,14 +4137,6 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(TRUE); } - if (lex_user->host.length > HOSTNAME_LENGTH || - lex_user->user.length > USERNAME_LENGTH) - { - my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER), - MYF(0)); - DBUG_RETURN(TRUE); - } - rw_rdlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -4678,6 +4663,32 @@ int open_grant_tables(THD *thd, TABLE_LIST *tables) DBUG_RETURN(0); } +ACL_USER *check_acl_user(LEX_USER *user_name, + uint *acl_acl_userdx) +{ + ACL_USER *acl_user= 0; + uint counter; + + safe_mutex_assert_owner(&acl_cache->lock); + + for (counter= 0 ; counter < acl_users.elements ; counter++) + { + const char *user,*host; + acl_user= dynamic_element(&acl_users, counter, ACL_USER*); + if (!(user=acl_user->user)) + user= ""; + if (!(host=acl_user->host.hostname)) + host= ""; + if (!strcmp(user_name->user.str,user) && + !my_strcasecmp(system_charset_info, user_name->host.str, host)) + break; + } + if (counter == acl_users.elements) + return 0; + + *acl_acl_userdx= counter; + return acl_user; +} /* Modify a privilege table. @@ -4726,7 +4737,6 @@ static int modify_grant_table(TABLE *table, Field *host_field, DBUG_RETURN(error); } - /* Handle a privilege table. @@ -5220,7 +5230,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) { result= TRUE; continue; - } + } + /* Search all in-memory structures and grant tables for a mention of the new user name. @@ -5361,7 +5372,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) result= TRUE; } } - + /* Rebuild 'acl_check_hosts' since 'acl_users' has been modified */ rebuild_check_host(); @@ -5413,8 +5424,6 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) } if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE)) { - sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not " - "exists", lex_user->user.str, lex_user->host.str); result= -1; continue; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 5383bb52aaa..c29c610b200 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -34,7 +34,8 @@ HASH open_cache; /* Used by mysql_test */ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, const char *name, const char *alias, - TABLE_LIST *table_list, MEM_ROOT *mem_root); + TABLE_LIST *table_list, MEM_ROOT *mem_root, + uint flags); static void free_cache_entry(TABLE *entry); static void mysql_rm_tmp_tables(void); static bool open_new_frm(THD *thd, const char *path, const char *alias, @@ -1108,7 +1109,7 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; if (open_unireg_entry(thd, table, db, table_name, table_name, 0, - thd->mem_root) || + thd->mem_root, 0) || !(table->s->table_cache_key= memdup_root(&table->mem_root, (char*) key, key_length))) { @@ -1311,7 +1312,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, VOID(pthread_mutex_lock(&LOCK_open)); if (!open_unireg_entry(thd, table, table_list->db, table_list->table_name, - alias, table_list, mem_root)) + alias, table_list, mem_root, 0)) { DBUG_ASSERT(table_list->view != 0); VOID(pthread_mutex_unlock(&LOCK_open)); @@ -1391,6 +1392,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, else { TABLE_SHARE *share; + int error; /* Free cache if too big */ while (open_cache.records > table_cache_size && unused_tables) VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ @@ -1401,9 +1403,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(NULL); } - if (open_unireg_entry(thd, table, table_list->db, table_list->table_name, - alias, table_list, mem_root) || - (!table_list->view && + error= open_unireg_entry(thd, table, table_list->db, + table_list->table_name, + alias, table_list, mem_root, + (flags & OPEN_VIEW_NO_PARSE)); + if ((error > 0) || + (!table_list->view && !error && !(table->s->table_cache_key= memdup_root(&table->mem_root, (char*) key, key_length)))) @@ -1413,8 +1418,15 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(NULL); } - if (table_list->view) + if (table_list->view || error < 0) { + /* + VIEW not really opened, only frm were read. + Set 1 as a flag here + */ + if (error < 0) + table_list->view= (st_lex*)1; + my_free((gptr)table, MYF(0)); VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(0); // VIEW @@ -1521,7 +1533,7 @@ bool reopen_table(TABLE *table,bool locked) safe_mutex_assert_owner(&LOCK_open); if (open_unireg_entry(table->in_use, &tmp, db, table_name, - table->alias, 0, table->in_use->mem_root)) + table->alias, 0, table->in_use->mem_root, 0)) goto end; free_io_cache(table); @@ -1851,6 +1863,8 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name) alias Alias name table_desc TABLE_LIST descriptor (used with views) mem_root temporary mem_root for parsing + flags the OPEN_VIEW_NO_PARSE flag to be passed to + openfrm()/open_new_frm() NOTES Extra argument for open is taken from thd->open_options @@ -1861,7 +1875,8 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name) */ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, const char *name, const char *alias, - TABLE_LIST *table_desc, MEM_ROOT *mem_root) + TABLE_LIST *table_desc, MEM_ROOT *mem_root, + uint flags) { char path[FN_REFLEN]; int error; @@ -1873,14 +1888,16 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY | NO_ERR_ON_NEW_FRM), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | + (flags & OPEN_VIEW_NO_PARSE), thd->open_options, entry)) && (error != 5 || (fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME), open_new_frm(thd, path, alias, db, name, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX | HA_TRY_READ_ONLY), - READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, + READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD | + (flags & OPEN_VIEW_NO_PARSE), thd->open_options, entry, table_desc, mem_root)))) { @@ -1962,7 +1979,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, } if (error == 5) - DBUG_RETURN(0); // we have just opened VIEW + DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0); // we have just opened VIEW /* We can't mark all tables in 'mysql' database as system since we don't @@ -4041,36 +4058,48 @@ store_top_level_join_columns(THD *thd, TABLE_LIST *table_ref, if (table_ref->nested_join) { List_iterator_fast<TABLE_LIST> nested_it(table_ref->nested_join->join_list); - TABLE_LIST *cur_left_neighbor= nested_it++; - TABLE_LIST *cur_right_neighbor= NULL; + TABLE_LIST *same_level_left_neighbor= nested_it++; + TABLE_LIST *same_level_right_neighbor= NULL; + /* Left/right-most neighbors, possibly at higher levels in the join tree. */ + TABLE_LIST *real_left_neighbor, *real_right_neighbor; - while (cur_left_neighbor) + while (same_level_left_neighbor) { - TABLE_LIST *cur_table_ref= cur_left_neighbor; - cur_left_neighbor= nested_it++; + TABLE_LIST *cur_table_ref= same_level_left_neighbor; + same_level_left_neighbor= nested_it++; /* The order of RIGHT JOIN operands is reversed in 'join list' to transform it into a LEFT JOIN. However, in this procedure we need the join operands in their lexical order, so below we reverse the - join operands. Notice that this happens only in the first loop, and - not in the second one, as in the second loop cur_left_neighbor == NULL. - This is the correct behavior, because the second loop - sets cur_table_ref reference correctly after the join operands are + join operands. Notice that this happens only in the first loop, + and not in the second one, as in the second loop + same_level_left_neighbor == NULL. + This is the correct behavior, because the second loop sets + cur_table_ref reference correctly after the join operands are swapped in the first loop. */ - if (cur_left_neighbor && + if (same_level_left_neighbor && cur_table_ref->outer_join & JOIN_TYPE_RIGHT) { /* This can happen only for JOIN ... ON. */ DBUG_ASSERT(table_ref->nested_join->join_list.elements == 2); - swap_variables(TABLE_LIST*, cur_left_neighbor, cur_table_ref); + swap_variables(TABLE_LIST*, same_level_left_neighbor, cur_table_ref); } + /* + Pick the parent's left and right neighbors if there are no immediate + neighbors at the same level. + */ + real_left_neighbor= (same_level_left_neighbor) ? + same_level_left_neighbor : left_neighbor; + real_right_neighbor= (same_level_right_neighbor) ? + same_level_right_neighbor : right_neighbor; + if (cur_table_ref->nested_join && store_top_level_join_columns(thd, cur_table_ref, - cur_left_neighbor, cur_right_neighbor)) + real_left_neighbor, real_right_neighbor)) goto err; - cur_right_neighbor= cur_table_ref; + same_level_right_neighbor= cur_table_ref; } } @@ -4424,7 +4453,20 @@ bool setup_tables(THD *thd, Name_resolution_context *context, uint tablenr= 0; DBUG_ENTER("setup_tables"); - context->table_list= context->first_name_resolution_table= tables; + /* + Due to the various call paths that lead to setup_tables() it may happen + that context->table_list and context->first_name_resolution_table can be + NULL (this is typically done when creating TABLE_LISTs internally). + TODO: + Investigate all cases when this my happen, initialize the name resolution + context correctly in all those places, and remove the context reset below. + */ + if (!context->table_list || !context->first_name_resolution_table) + { + /* Test whether the context is in a consistent state. */ + DBUG_ASSERT(!context->first_name_resolution_table && !context->table_list); + context->table_list= context->first_name_resolution_table= tables; + } /* this is used for INSERT ... SELECT. @@ -4534,9 +4576,11 @@ bool setup_tables_and_check_access(THD *thd, TABLE_LIST *tables, Item **conds, TABLE_LIST **leaves, bool select_insert, + ulong want_access_first, ulong want_access) { TABLE_LIST *leaves_tmp = NULL; + bool first_table= true; if (setup_tables (thd, context, from_clause, tables, conds, &leaves_tmp, select_insert)) @@ -4546,13 +4590,16 @@ bool setup_tables_and_check_access(THD *thd, *leaves = leaves_tmp; for (; leaves_tmp; leaves_tmp= leaves_tmp->next_leaf) + { if (leaves_tmp->belong_to_view && - check_single_table_access(thd, want_access, leaves_tmp)) + check_single_table_access(thd, first_table ? want_access_first : + want_access, leaves_tmp)) { tables->hide_view_error(thd); return TRUE; } - + first_table= false; + } return FALSE; } @@ -4947,12 +4994,17 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values, bool ignore_errors) { List_iterator_fast<Item> f(fields),v(values); - Item *value; + Item *value, *fld; Item_field *field; DBUG_ENTER("fill_record"); - while ((field=(Item_field*) f++)) + while ((fld= f++)) { + if (!(field= fld->filed_for_view_update())) + { + my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name); + DBUG_RETURN(TRUE); + } value=v++; Field *rfield= field->field; TABLE *table= rfield->table; @@ -5362,7 +5414,8 @@ open_new_frm(THD *thd, const char *path, const char *alias, my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE"); goto err; } - if (mysql_make_view(thd, parser, table_desc)) + if (mysql_make_view(thd, parser, table_desc, + (prgflag & OPEN_VIEW_NO_PARSE))) goto err; } else diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index f8f7bde3a62..ff033b69f98 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -565,21 +565,62 @@ byte *query_cache_query_get_key(const byte *record, uint *length, *****************************************************************************/ /* + Note on double-check locking (DCL) usage. + + Below, in query_cache_insert(), query_cache_abort() and + query_cache_end_of_result() we use what is called double-check + locking (DCL) for NET::query_cache_query. I.e. we test it first + without a lock, and, if positive, test again under the lock. + + This means that if we see 'NET::query_cache_query == 0' without a + lock we will skip the operation. But this is safe here: when we + started to cache a query, we called Query_cache::store_query(), and + NET::query_cache_query was set to non-zero in this thread (and the + thread always sees results of its memory operations, mutex or not). + If later we see 'NET::query_cache_query == 0' without locking a + mutex, that may only mean that some other thread have reset it by + invalidating the query. Skipping the operation in this case is the + right thing to do, as NET::query_cache_query won't get non-zero for + this query again. + + See also comments in Query_cache::store_query() and + Query_cache::send_result_to_client(). + + NOTE, however, that double-check locking is not applicable in + 'invalidate' functions, as we may erroneously skip invalidation, + because the thread doing invalidation may never see non-zero + NET::query_cache_query. +*/ + + +void query_cache_init_query(NET *net) +{ + /* + It is safe to initialize 'NET::query_cache_query' without a lock + here, because before it will be accessed from different threads it + will be set in this thread under a lock, and access from the same + thread is always safe. + */ + net->query_cache_query= 0; +} + + +/* Insert the packet into the query cache. - This should only be called if net->query_cache_query != 0 */ void query_cache_insert(NET *net, const char *packet, ulong length) { DBUG_ENTER("query_cache_insert"); + /* See the comment on double-check locking usage above. */ + if (net->query_cache_query == 0) + DBUG_VOID_RETURN; + STRUCT_LOCK(&query_cache.structure_guard_mutex); - /* - It is very unlikely that following condition is TRUE (it is possible - only if other thread is resizing cache), so we check it only after guard - mutex lock - */ - if (unlikely(query_cache.query_cache_size == 0)) + + if (unlikely(query_cache.query_cache_size == 0 || + query_cache.flush_in_progress)) { STRUCT_UNLOCK(&query_cache.structure_guard_mutex); DBUG_VOID_RETURN; @@ -616,10 +657,10 @@ void query_cache_insert(NET *net, const char *packet, ulong length) header->result(result); header->last_pkt_nr= net->pkt_nr; BLOCK_UNLOCK_WR(query_block); + DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0);); } else STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0);); DBUG_VOID_RETURN; } @@ -628,33 +669,33 @@ void query_cache_abort(NET *net) { DBUG_ENTER("query_cache_abort"); - if (net->query_cache_query != 0) // Quick check on unlocked structure + /* See the comment on double-check locking usage above. */ + if (net->query_cache_query == 0) + DBUG_VOID_RETURN; + + STRUCT_LOCK(&query_cache.structure_guard_mutex); + + if (unlikely(query_cache.query_cache_size == 0 || + query_cache.flush_in_progress)) { - STRUCT_LOCK(&query_cache.structure_guard_mutex); - /* - It is very unlikely that following condition is TRUE (it is possible - only if other thread is resizing cache), so we check it only after guard - mutex lock - */ - if (unlikely(query_cache.query_cache_size == 0)) - { - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - DBUG_VOID_RETURN; - } + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + DBUG_VOID_RETURN; + } - Query_cache_block *query_block = ((Query_cache_block*) - net->query_cache_query); - if (query_block) // Test if changed by other thread - { - DUMP(&query_cache); - BLOCK_LOCK_WR(query_block); - // The following call will remove the lock on query_block - query_cache.free_query(query_block); - } - net->query_cache_query=0; + Query_cache_block *query_block= ((Query_cache_block*) + net->query_cache_query); + if (query_block) // Test if changed by other thread + { + DUMP(&query_cache); + BLOCK_LOCK_WR(query_block); + // The following call will remove the lock on query_block + query_cache.free_query(query_block); + net->query_cache_query= 0; DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); } + + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + DBUG_VOID_RETURN; } @@ -663,60 +704,65 @@ void query_cache_end_of_result(THD *thd) { DBUG_ENTER("query_cache_end_of_result"); - if (thd->net.query_cache_query != 0) // Quick check on unlocked structure - { + /* See the comment on double-check locking usage above. */ + if (thd->net.query_cache_query == 0) + DBUG_VOID_RETURN; + #ifdef EMBEDDED_LIBRARY - query_cache_insert(&thd->net, (char*)thd, - emb_count_querycache_size(thd)); + query_cache_insert(&thd->net, (char*)thd, + emb_count_querycache_size(thd)); #endif - STRUCT_LOCK(&query_cache.structure_guard_mutex); - /* - It is very unlikely that following condition is TRUE (it is possible - only if other thread is resizing cache), so we check it only after guard - mutex lock - */ - if (unlikely(query_cache.query_cache_size == 0)) - { - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - DBUG_VOID_RETURN; - } - Query_cache_block *query_block = ((Query_cache_block*) - thd->net.query_cache_query); - if (query_block) - { - DUMP(&query_cache); - BLOCK_LOCK_WR(query_block); - Query_cache_query *header = query_block->query(); - Query_cache_block *last_result_block = header->result()->prev; - ulong allign_size = ALIGN_SIZE(last_result_block->used); - ulong len = max(query_cache.min_allocation_unit, allign_size); - if (last_result_block->length >= query_cache.min_allocation_unit + len) - query_cache.split_block(last_result_block,len); - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + STRUCT_LOCK(&query_cache.structure_guard_mutex); + + if (unlikely(query_cache.query_cache_size == 0 || + query_cache.flush_in_progress)) + { + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + DBUG_VOID_RETURN; + } + + Query_cache_block *query_block= ((Query_cache_block*) + thd->net.query_cache_query); + if (query_block) + { + DUMP(&query_cache); + BLOCK_LOCK_WR(query_block); + Query_cache_query *header= query_block->query(); + Query_cache_block *last_result_block= header->result()->prev; + ulong allign_size= ALIGN_SIZE(last_result_block->used); + ulong len= max(query_cache.min_allocation_unit, allign_size); + if (last_result_block->length >= query_cache.min_allocation_unit + len) + query_cache.split_block(last_result_block,len); #ifndef DBUG_OFF - if (header->result() == 0) - { - DBUG_PRINT("error", ("end of data whith no result. query '%s'", - header->query())); - query_cache.wreck(__LINE__, ""); - DBUG_VOID_RETURN; - } -#endif - header->found_rows(current_thd->limit_found_rows); - header->result()->type = Query_cache_block::RESULT; - header->writer(0); - BLOCK_UNLOCK_WR(query_block); - } - else + if (header->result() == 0) { - // Cache was flushed or resized and query was deleted => do nothing + DBUG_PRINT("error", ("end of data whith no result. query '%s'", + header->query())); + query_cache.wreck(__LINE__, ""); + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + + DBUG_VOID_RETURN; } - thd->net.query_cache_query=0; - DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0);); +#endif + header->found_rows(current_thd->limit_found_rows); + header->result()->type= Query_cache_block::RESULT; + header->writer(0); + thd->net.query_cache_query= 0; + DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1);); + + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + + BLOCK_UNLOCK_WR(query_block); + } + else + { + // Cache was flushed or resized and query was deleted => do nothing + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); } + DBUG_VOID_RETURN; } @@ -762,8 +808,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg) query_cache_size_arg)); DBUG_ASSERT(initialized); STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) - free_cache(); + free_cache(); query_cache_size= query_cache_size_arg; ::query_cache_size= init_cache(); STRUCT_UNLOCK(&structure_guard_mutex); @@ -784,7 +829,15 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) TABLE_COUNTER_TYPE local_tables; ulong tot_length; DBUG_ENTER("Query_cache::store_query"); - if (query_cache_size == 0 || thd->locked_tables) + /* + Testing 'query_cache_size' without a lock here is safe: the thing + we may loose is that the query won't be cached, but we save on + mutex locking in the case when query cache is disabled or the + query is uncachable. + + See also a note on double-check locking usage above. + */ + if (thd->locked_tables || query_cache_size == 0) DBUG_VOID_RETURN; uint8 tables_type= 0; @@ -836,9 +889,9 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu", acquiring the query cache mutex. */ ha_release_temporary_latches(thd); - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size == 0) + STRUCT_LOCK(&structure_guard_mutex); + if (query_cache_size == 0 || flush_in_progress) { STRUCT_UNLOCK(&structure_guard_mutex); DBUG_VOID_RETURN; @@ -912,11 +965,12 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu", double_linked_list_simple_include(query_block, &queries_blocks); inserts++; queries_in_cache++; - STRUCT_UNLOCK(&structure_guard_mutex); - net->query_cache_query= (gptr) query_block; header->writer(net); header->tables_type(tables_type); + + STRUCT_UNLOCK(&structure_guard_mutex); + // init_n_lock make query block locked BLOCK_UNLOCK_WR(query_block); } @@ -970,12 +1024,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) Query_cache_query_flags flags; DBUG_ENTER("Query_cache::send_result_to_client"); - if (query_cache_size == 0 || thd->locked_tables || - thd->variables.query_cache_type == 0) - goto err; + /* + Testing 'query_cache_size' without a lock here is safe: the thing + we may loose is that the query won't be served from cache, but we + save on mutex locking in the case when query cache is disabled. - /* Check that we haven't forgot to reset the query cache variables */ - DBUG_ASSERT(thd->net.query_cache_query == 0); + See also a note on double-check locking usage above. + */ + if (thd->locked_tables || thd->variables.query_cache_type == 0 || + query_cache_size == 0) + goto err; if (!thd->lex->safe_to_cache_query) { @@ -1011,11 +1069,15 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) } STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size == 0) + if (query_cache_size == 0 || flush_in_progress) { DBUG_PRINT("qcache", ("query cache disabled")); goto err_unlock; } + + /* Check that we haven't forgot to reset the query cache variables */ + DBUG_ASSERT(thd->net.query_cache_query == 0); + Query_cache_block *query_block; tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE; @@ -1241,45 +1303,43 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used, my_bool using_transactions) { DBUG_ENTER("Query_cache::invalidate (table list)"); - if (query_cache_size > 0) + STRUCT_LOCK(&structure_guard_mutex); + if (query_cache_size > 0 && !flush_in_progress) { - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) - { - DUMP(this); + DUMP(this); - using_transactions = using_transactions && - (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)); - for (; tables_used; tables_used= tables_used->next_local) - { - DBUG_ASSERT(!using_transactions || tables_used->table!=0); - if (tables_used->derived) - continue; - if (using_transactions && - (tables_used->table->file->table_cache_type() == - HA_CACHE_TBL_TRANSACT)) - /* - Tables_used->table can't be 0 in transaction. - Only 'drop' invalidate not opened table, but 'drop' - force transaction finish. - */ - thd->add_changed_table(tables_used->table); - else - invalidate_table(tables_used); - } + using_transactions= using_transactions && + (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)); + for (; tables_used; tables_used= tables_used->next_local) + { + DBUG_ASSERT(!using_transactions || tables_used->table!=0); + if (tables_used->derived) + continue; + if (using_transactions && + (tables_used->table->file->table_cache_type() == + HA_CACHE_TBL_TRANSACT)) + /* + Tables_used->table can't be 0 in transaction. + Only 'drop' invalidate not opened table, but 'drop' + force transaction finish. + */ + thd->add_changed_table(tables_used->table); + else + invalidate_table(tables_used); } - STRUCT_UNLOCK(&structure_guard_mutex); } + STRUCT_UNLOCK(&structure_guard_mutex); + DBUG_VOID_RETURN; } void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used) { DBUG_ENTER("Query_cache::invalidate (changed table list)"); - if (query_cache_size > 0 && tables_used) + if (tables_used) { STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) + if (query_cache_size > 0 && !flush_in_progress) { DUMP(this); for (; tables_used; tables_used= tables_used->next) @@ -1309,10 +1369,10 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used) void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used) { DBUG_ENTER("Query_cache::invalidate_locked_for_write"); - if (query_cache_size > 0 && tables_used) + if (tables_used) { STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) + if (query_cache_size > 0 && !flush_in_progress) { DUMP(this); for (; tables_used; tables_used= tables_used->next_local) @@ -1336,21 +1396,19 @@ void Query_cache::invalidate(THD *thd, TABLE *table, { DBUG_ENTER("Query_cache::invalidate (table)"); - if (query_cache_size > 0) + STRUCT_LOCK(&structure_guard_mutex); + if (query_cache_size > 0 && !flush_in_progress) { - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) - { - using_transactions = using_transactions && - (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)); - if (using_transactions && - (table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT)) - thd->add_changed_table(table); - else - invalidate_table(table); - } - STRUCT_UNLOCK(&structure_guard_mutex); + using_transactions= using_transactions && + (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)); + if (using_transactions && + (table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT)) + thd->add_changed_table(table); + else + invalidate_table(table); } + STRUCT_UNLOCK(&structure_guard_mutex); + DBUG_VOID_RETURN; } @@ -1359,20 +1417,18 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length, { DBUG_ENTER("Query_cache::invalidate (key)"); - if (query_cache_size > 0) + STRUCT_LOCK(&structure_guard_mutex); + if (query_cache_size > 0 && !flush_in_progress) { - using_transactions = using_transactions && + using_transactions= using_transactions && (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)); if (using_transactions) // used for innodb => has_transactions() is TRUE thd->add_changed_table(key, key_length); else - { - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) - invalidate_table((byte*)key, key_length); - STRUCT_UNLOCK(&structure_guard_mutex); - } + invalidate_table((byte*)key, key_length); } + STRUCT_UNLOCK(&structure_guard_mutex); + DBUG_VOID_RETURN; } @@ -1383,38 +1439,36 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length, void Query_cache::invalidate(char *db) { DBUG_ENTER("Query_cache::invalidate (db)"); - if (query_cache_size > 0) + STRUCT_LOCK(&structure_guard_mutex); + if (query_cache_size > 0 && !flush_in_progress) { - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) - { - DUMP(this); + DUMP(this); restart_search: - if (tables_blocks) + if (tables_blocks) + { + Query_cache_block *curr= tables_blocks; + Query_cache_block *next; + do { - Query_cache_block *curr= tables_blocks; - Query_cache_block *next; - do - { - next= curr->next; - if (strcmp(db, (char*)(curr->table()->db())) == 0) - invalidate_table(curr); - /* - invalidate_table can freed block on which point 'next' (if - table of this block used only in queries which was deleted - by invalidate_table). As far as we do not allocate new blocks - and mark all headers of freed blocks as 'FREE' (even if they are - merged with other blocks) we can just test type of block - to be sure that block is not deleted - */ - if (next->type == Query_cache_block::FREE) - goto restart_search; - curr= next; - } while (curr != tables_blocks); - } + next= curr->next; + if (strcmp(db, (char*)(curr->table()->db())) == 0) + invalidate_table(curr); + /* + invalidate_table can freed block on which point 'next' (if + table of this block used only in queries which was deleted + by invalidate_table). As far as we do not allocate new blocks + and mark all headers of freed blocks as 'FREE' (even if they are + merged with other blocks) we can just test type of block + to be sure that block is not deleted + */ + if (next->type == Query_cache_block::FREE) + goto restart_search; + curr= next; + } while (curr != tables_blocks); } - STRUCT_UNLOCK(&structure_guard_mutex); } + STRUCT_UNLOCK(&structure_guard_mutex); + DBUG_VOID_RETURN; } @@ -1422,23 +1476,22 @@ void Query_cache::invalidate(char *db) void Query_cache::invalidate_by_MyISAM_filename(const char *filename) { DBUG_ENTER("Query_cache::invalidate_by_MyISAM_filename"); - if (query_cache_size > 0) + + STRUCT_LOCK(&structure_guard_mutex); + if (query_cache_size > 0 && !flush_in_progress) { /* Calculate the key outside the lock to make the lock shorter */ char key[MAX_DBKEY_LENGTH]; uint32 db_length; uint key_length= filename_2_table_key(key, filename, &db_length); - STRUCT_LOCK(&structure_guard_mutex); - if (query_cache_size > 0) // Safety if cache removed - { - Query_cache_block *table_block; - if ((table_block = (Query_cache_block*) hash_search(&tables, - (byte*) key, - key_length))) - invalidate_table(table_block); - } - STRUCT_UNLOCK(&structure_guard_mutex); + Query_cache_block *table_block; + if ((table_block = (Query_cache_block*) hash_search(&tables, + (byte*) key, + key_length))) + invalidate_table(table_block); } + STRUCT_UNLOCK(&structure_guard_mutex); + DBUG_VOID_RETURN; } @@ -1483,7 +1536,12 @@ void Query_cache::destroy() } else { + /* Underlying code expects the lock. */ + STRUCT_LOCK(&structure_guard_mutex); free_cache(); + STRUCT_UNLOCK(&structure_guard_mutex); + + pthread_cond_destroy(&COND_flush_finished); pthread_mutex_destroy(&structure_guard_mutex); initialized = 0; } @@ -1499,6 +1557,8 @@ void Query_cache::init() { DBUG_ENTER("Query_cache::init"); pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST); + pthread_cond_init(&COND_flush_finished, NULL); + flush_in_progress= FALSE; initialized = 1; DBUG_VOID_RETURN; } @@ -1694,6 +1754,17 @@ void Query_cache::make_disabled() } +/* + free_cache() - free all resources allocated by the cache. + + SYNOPSIS + free_cache() + + DESCRIPTION + This function frees all resources allocated by the cache. You + have to call init_cache() before using the cache again. +*/ + void Query_cache::free_cache() { DBUG_ENTER("Query_cache::free_cache"); @@ -1728,17 +1799,51 @@ void Query_cache::free_cache() Free block data *****************************************************************************/ + /* - The following assumes we have a lock on the cache + flush_cache() - flush the cache. + + SYNOPSIS + flush_cache() + + DESCRIPTION + This function will flush cache contents. It assumes we have + 'structure_guard_mutex' locked. The function sets the + flush_in_progress flag and releases the lock, so other threads may + proceed skipping the cache as if it is disabled. Concurrent + flushes are performed in turn. */ void Query_cache::flush_cache() { + /* + If there is flush in progress, wait for it to finish, and then do + our flush. This is necessary because something could be added to + the cache before we acquire the lock again, and some code (like + Query_cache::free_cache()) depends on the fact that after the + flush the cache is empty. + */ + while (flush_in_progress) + pthread_cond_wait(&COND_flush_finished, &structure_guard_mutex); + + /* + Setting 'flush_in_progress' will prevent other threads from using + the cache while we are in the middle of the flush, and we release + the lock so that other threads won't block. + */ + flush_in_progress= TRUE; + STRUCT_UNLOCK(&structure_guard_mutex); + + my_hash_reset(&queries); while (queries_blocks != 0) { BLOCK_LOCK_WR(queries_blocks); - free_query(queries_blocks); + free_query_internal(queries_blocks); } + + STRUCT_LOCK(&structure_guard_mutex); + flush_in_progress= FALSE; + pthread_cond_signal(&COND_flush_finished); } /* @@ -1784,36 +1889,48 @@ my_bool Query_cache::free_old_query() DBUG_RETURN(1); // Nothing to remove } + /* - Free query from query cache. - query_block must be locked for writing. - This function will remove (and destroy) the lock for the query. + free_query_internal() - free query from query cache. + + SYNOPSIS + free_query_internal() + query_block Query_cache_block representing the query + + DESCRIPTION + This function will remove the query from a cache, and place its + memory blocks to the list of free blocks. 'query_block' must be + locked for writing, this function will release (and destroy) this + lock. + + NOTE + 'query_block' should be removed from 'queries' hash _before_ + calling this method, as the lock will be destroyed here. */ -void Query_cache::free_query(Query_cache_block *query_block) +void Query_cache::free_query_internal(Query_cache_block *query_block) { - DBUG_ENTER("Query_cache::free_query"); + DBUG_ENTER("Query_cache::free_query_internal"); DBUG_PRINT("qcache", ("free query 0x%lx %lu bytes result", (ulong) query_block, query_block->query()->length() )); queries_in_cache--; - hash_delete(&queries,(byte *) query_block); - Query_cache_query *query = query_block->query(); + Query_cache_query *query= query_block->query(); if (query->writer() != 0) { /* Tell MySQL that this query should not be cached anymore */ - query->writer()->query_cache_query = 0; + query->writer()->query_cache_query= 0; query->writer(0); } double_linked_list_exclude(query_block, &queries_blocks); - Query_cache_block_table *table=query_block->table(0); + Query_cache_block_table *table= query_block->table(0); - for (TABLE_COUNTER_TYPE i=0; i < query_block->n_tables; i++) + for (TABLE_COUNTER_TYPE i= 0; i < query_block->n_tables; i++) unlink_table(table++); - Query_cache_block *result_block = query->result(); + Query_cache_block *result_block= query->result(); /* The following is true when query destruction was called and no results @@ -1827,11 +1944,11 @@ void Query_cache::free_query(Query_cache_block *query_block) refused++; inserts--; } - Query_cache_block *block = result_block; + Query_cache_block *block= result_block; do { - Query_cache_block *current = block; - block = block->next; + Query_cache_block *current= block; + block= block->next; free_memory_block(current); } while (block != result_block); } @@ -1848,6 +1965,32 @@ void Query_cache::free_query(Query_cache_block *query_block) DBUG_VOID_RETURN; } + +/* + free_query() - free query from query cache. + + SYNOPSIS + free_query() + query_block Query_cache_block representing the query + + DESCRIPTION + This function will remove 'query_block' from 'queries' hash, and + then call free_query_internal(), which see. +*/ + +void Query_cache::free_query(Query_cache_block *query_block) +{ + DBUG_ENTER("Query_cache::free_query"); + DBUG_PRINT("qcache", ("free query 0x%lx %lu bytes result", + (ulong) query_block, + query_block->query()->length() )); + + hash_delete(&queries,(byte *) query_block); + free_query_internal(query_block); + + DBUG_VOID_RETURN; +} + /***************************************************************************** Query data creation *****************************************************************************/ @@ -2431,12 +2574,8 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min, if (!under_guard) { STRUCT_LOCK(&structure_guard_mutex); - /* - It is very unlikely that following condition is TRUE (it is possible - only if other thread is resizing cache), so we check it only after - guard mutex lock - */ - if (unlikely(query_cache.query_cache_size == 0)) + + if (unlikely(query_cache.query_cache_size == 0 || flush_in_progress)) { STRUCT_UNLOCK(&structure_guard_mutex); DBUG_RETURN(0); @@ -2892,11 +3031,9 @@ static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used, (query without tables are not cached) */ -TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len, - char *query, - LEX *lex, - TABLE_LIST *tables_used, - uint8 *tables_type) +TABLE_COUNTER_TYPE +Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex, + TABLE_LIST *tables_used, uint8 *tables_type) { TABLE_COUNTER_TYPE table_count; DBUG_ENTER("Query_cache::is_cacheable"); @@ -2979,13 +3116,10 @@ my_bool Query_cache::ask_handler_allowance(THD *thd, void Query_cache::pack_cache() { DBUG_ENTER("Query_cache::pack_cache"); + STRUCT_LOCK(&structure_guard_mutex); - /* - It is very unlikely that following condition is TRUE (it is possible - only if other thread is resizing cache), so we check it only after - guard mutex lock - */ - if (unlikely(query_cache_size == 0)) + + if (unlikely(query_cache_size == 0 || flush_in_progress)) { STRUCT_UNLOCK(&structure_guard_mutex); DBUG_VOID_RETURN; @@ -3300,7 +3434,7 @@ my_bool Query_cache::join_results(ulong join_limit) DBUG_ENTER("Query_cache::join_results"); STRUCT_LOCK(&structure_guard_mutex); - if (queries_blocks != 0) + if (queries_blocks != 0 && !flush_in_progress) { DBUG_ASSERT(query_cache_size > 0); Query_cache_block *block = queries_blocks; @@ -3587,31 +3721,23 @@ void Query_cache::tables_dump() } -my_bool Query_cache::check_integrity(bool not_locked) +my_bool Query_cache::check_integrity(bool locked) { my_bool result = 0; uint i; DBUG_ENTER("check_integrity"); - if (query_cache_size == 0) + if (!locked) + STRUCT_LOCK(&structure_guard_mutex); + + if (unlikely(query_cache_size == 0 || flush_in_progress)) { + if (!locked) + STRUCT_UNLOCK(&query_cache.structure_guard_mutex); + DBUG_PRINT("qcache", ("Query Cache not initialized")); DBUG_RETURN(0); } - if (!not_locked) - { - STRUCT_LOCK(&structure_guard_mutex); - /* - It is very unlikely that following condition is TRUE (it is possible - only if other thread is resizing cache), so we check it only after - guard mutex lock - */ - if (unlikely(query_cache_size == 0)) - { - STRUCT_UNLOCK(&query_cache.structure_guard_mutex); - DBUG_RETURN(0); - } - } if (hash_check(&queries)) { @@ -3856,7 +3982,7 @@ my_bool Query_cache::check_integrity(bool not_locked) } } DBUG_ASSERT(result == 0); - if (!not_locked) + if (!locked) STRUCT_UNLOCK(&structure_guard_mutex); DBUG_RETURN(result); } diff --git a/sql/sql_cache.h b/sql/sql_cache.h index 29d314d3c44..a66067159e2 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -195,7 +195,6 @@ extern "C" byte *query_cache_table_get_key(const byte *record, uint *length, my_bool not_used); } -void query_cache_insert(NET *thd, const char *packet, ulong length); extern "C" void query_cache_invalidate_by_MyISAM_filename(const char* filename); @@ -241,6 +240,12 @@ public: ulong free_memory, queries_in_cache, hits, inserts, refused, free_memory_blocks, total_blocks, lowmem_prunes; +private: + pthread_cond_t COND_flush_finished; + bool flush_in_progress; + + void free_query_internal(Query_cache_block *point); + protected: /* The following mutex is locked when searching or changing global @@ -249,6 +254,12 @@ protected: LOCK SEQUENCE (to prevent deadlocks): 1. structure_guard_mutex 2. query block (for operation inside query (query block/results)) + + Thread doing cache flush releases the mutex once it sets + flush_in_progress flag, so other threads may bypass the cache as + if it is disabled, not waiting for reset to finish. The exception + is other threads that were going to do cache flush---they'll wait + till the end of a flush operation. */ pthread_mutex_t structure_guard_mutex; byte *cache; // cache memory @@ -358,6 +369,7 @@ protected: If query is cacheable return number tables in query (query without tables not cached) */ + static TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex, TABLE_LIST *tables_used, uint8 *tables_type); @@ -410,6 +422,7 @@ protected: void destroy(); + friend void query_cache_init_query(NET *net); friend void query_cache_insert(NET *net, const char *packet, ulong length); friend void query_cache_end_of_result(THD *thd); friend void query_cache_abort(NET *net); @@ -435,6 +448,8 @@ protected: extern Query_cache query_cache; extern TYPELIB query_cache_type_typelib; +void query_cache_init_query(NET *net); +void query_cache_insert(NET *net, const char *packet, ulong length); void query_cache_end_of_result(THD *thd); void query_cache_abort(NET *net); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4cb9cfc53c6..093173ab949 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -224,7 +224,7 @@ THD::THD() #endif client_capabilities= 0; // minimalistic client net.last_error[0]=0; // If error on boot - net.query_cache_query=0; // If error on boot + query_cache_init_query(&net); // If error on boot ull=0; system_thread= cleanup_done= abort_on_warning= no_warnings_for_error= 0; peer_port= 0; // For SHOW PROCESSLIST @@ -1883,7 +1883,7 @@ bool select_dumpvar::send_data(List<Item> &items) { if ((xx=li++)) { - xx->check(); + xx->check(0); xx->update(); } } diff --git a/sql/sql_class.h b/sql/sql_class.h index 5134efcfb32..ed9f4b57f56 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -200,7 +200,7 @@ class MYSQL_LOG: public TC_LOG IO_CACHE log_file; IO_CACHE index_file; char *name; - char time_buff[20],db[NAME_LEN+1]; + char time_buff[20],db[NAME_BYTE_LEN+1]; char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN]; /* The max size before rotation (usable only if log_type == LOG_BIN: binary @@ -342,6 +342,7 @@ public: bool need_mutex); int find_next_log(LOG_INFO* linfo, bool need_mutex); int get_current_log(LOG_INFO* linfo); + int raw_get_current_log(LOG_INFO* linfo); uint next_file_id(); inline bool is_open() { return log_type != LOG_CLOSED; } inline char* get_index_fname() { return index_file_name;} @@ -2015,6 +2016,7 @@ class user_var_entry ulong length; query_id_t update_query_id, used_query_id; Item_result type; + bool unsigned_flag; double val_real(my_bool *null_value); longlong val_int(my_bool *null_value); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 902539dfdec..81508e4e9be 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -295,7 +295,6 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) create Where to store the read options DESCRIPTION - For now, only default-character-set is read. RETURN VALUES 0 File found @@ -384,6 +383,50 @@ err1: /* + Retrieve database options by name. Load database options file or fetch from + cache. + + SYNOPSIS + load_db_opt_by_name() + db_name Database name + db_create_info Where to store the database options + + DESCRIPTION + load_db_opt_by_name() is a shortcut for load_db_opt(). + + NOTE + Although load_db_opt_by_name() (and load_db_opt()) returns status of + the operation, it is useless usually and should be ignored. The problem + is that there are 1) system databases ("mysql") and 2) virtual + databases ("information_schema"), which do not contain options file. + So, load_db_opt[_by_name]() returns FALSE for these databases, but this + is not an error. + + load_db_opt[_by_name]() clears db_create_info structure in any case, so + even on failure it contains valid data. So, common use case is just + call load_db_opt[_by_name]() without checking return value and use + db_create_info right after that. + + RETURN VALUES (read NOTE!) + FALSE Success + TRUE Failed to retrieve options +*/ + +bool load_db_opt_by_name(THD *thd, const char *db_name, + HA_CREATE_INFO *db_create_info) +{ + char db_opt_path[FN_REFLEN]; + + strxnmov(db_opt_path, sizeof (db_opt_path) - 1, mysql_data_home, "/", + db_name, "/", MY_DB_OPT_FILE, NullS); + + unpack_filename(db_opt_path, db_opt_path); + + return load_db_opt(thd, db_opt_path, db_create_info); +} + + +/* Create a database SYNOPSIS @@ -1126,8 +1169,6 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check) { int path_length, db_length; char *db_name; - char path[FN_REFLEN]; - HA_CREATE_INFO create; bool system_db= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; @@ -1196,16 +1237,14 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check) } } #endif - (void) sprintf(path,"%s/%s", mysql_data_home, db_name); - path_length= unpack_dirname(path, path); // Convert if not UNIX - if (path_length && path[path_length-1] == FN_LIBCHAR) - path[path_length-1]= '\0'; // remove ending '\' - if (my_access(path,F_OK)) + + if (check_db_dir_existence(db_name)) { my_error(ER_BAD_DB_ERROR, MYF(0), db_name); my_free(db_name, MYF(0)); DBUG_RETURN(1); } + end: x_free(thd->db); DBUG_ASSERT(db_name == NULL || db_name[0] != '\0'); @@ -1221,8 +1260,10 @@ end: } else { - strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); + HA_CREATE_INFO create; + + load_db_opt_by_name(thd, db_name, &create); + thd->db_charset= create.default_table_charset ? create.default_table_charset : thd->variables.collation_server; @@ -1230,3 +1271,36 @@ end: } DBUG_RETURN(0); } + + +/* + Check if there is directory for the database name. + + SYNOPSIS + check_db_dir_existence() + db_name database name + + RETURN VALUES + FALSE There is directory for the specified database name. + TRUE The directory does not exist. +*/ + +bool check_db_dir_existence(const char *db_name) +{ + char db_dir_path[FN_REFLEN]; + uint db_dir_path_len; + + strxnmov(db_dir_path, sizeof (db_dir_path) - 1, mysql_data_home, "/", + db_name, NullS); + + db_dir_path_len= unpack_dirname(db_dir_path, db_dir_path); + + /* Remove trailing '/' or '\' if exists. */ + + if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR) + db_dir_path[db_dir_path_len - 1]= 0; + + /* Check access. */ + + return my_access(db_dir_path, F_OK); +} diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 381d1a71e31..e420022b8a1 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -91,6 +91,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, /* Handler didn't support fast delete; Delete rows one by one */ } + if (conds) + { + Item::cond_result result; + conds= remove_eq_conds(thd, conds, &result); + if (result == Item::COND_FALSE) // Impossible where + limit= 0; + } + table->used_keys.clear_all(); table->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table, 0, 0, conds, 0, &error); @@ -342,7 +350,7 @@ bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) &thd->lex->select_lex.top_join_list, table_list, conds, &select_lex->leaf_tables, FALSE, - DELETE_ACL) || + DELETE_ACL, SELECT_ACL) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || setup_ftfuncs(select_lex)) DBUG_RETURN(TRUE); @@ -405,7 +413,7 @@ bool mysql_multi_delete_prepare(THD *thd) &thd->lex->select_lex.top_join_list, lex->query_tables, &lex->select_lex.where, &lex->select_lex.leaf_tables, FALSE, - DELETE_ACL)) + DELETE_ACL, SELECT_ACL)) DBUG_RETURN(TRUE); diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 19811efbb12..ebd515bd209 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -139,14 +139,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, } if (thd->spcont && - thd->spcont->find_handler(code, - ((int) level >= - (int) MYSQL_ERROR::WARN_LEVEL_WARN && - thd->really_abort_on_warning()) ? - MYSQL_ERROR::WARN_LEVEL_ERROR : level)) + thd->spcont->handle_error(code, level, thd)) { - if (! thd->spcont->found_handler_here()) - thd->net.report_error= 1; /* Make "select" abort correctly */ DBUG_RETURN(NULL); } query_cache_abort(&thd->net); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 57805da608b..b70d11e4b26 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -411,6 +411,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table= table_list->table; context= &thd->lex->select_lex.context; + /* + These three asserts test the hypothesis that the resetting of the name + resolution context below is not necessary at all since the list of local + tables for INSERT always consists of one table. + */ + DBUG_ASSERT(!table_list->next_local); + DBUG_ASSERT(!context->table_list->next_local); + DBUG_ASSERT(!context->first_name_resolution_table->next_name_resolution_table); + /* Save the state of the current name resolution context. */ ctx_state.save_state(context, table_list); @@ -847,7 +856,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, &thd->lex->select_lex.top_join_list, table_list, where, &thd->lex->select_lex.leaf_tables, - select_insert, SELECT_ACL)) + select_insert, INSERT_ACL, SELECT_ACL)) DBUG_RETURN(TRUE); if (insert_into_view && !fields.elements) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 479db7b5b99..43aeea2bf53 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -126,6 +126,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->param_list.empty(); lex->view_list.empty(); lex->prepared_stmt_params.empty(); + lex->auxiliary_table_list.empty(); lex->unit.next= lex->unit.master= lex->unit.link_next= lex->unit.return_to= 0; lex->unit.prev= lex->unit.link_prev= 0; @@ -557,23 +558,20 @@ int MYSQLlex(void *arg, void *yythd) case MY_LEX_IDENT_OR_NCHAR: if (yyPeek() != '\'') - { // Found x'hex-number' + { state= MY_LEX_IDENT; break; } - yyGet(); // Skip ' - while ((c = yyGet()) && (c !='\'')) ; - length=(lex->ptr - lex->tok_start); // Length of hexnum+3 - if (c != '\'') + /* Found N'string' */ + lex->tok_start++; // Skip N + yySkip(); // Skip ' + if (!(yylval->lex_str.str = get_text(lex))) { - return(ABORT_SYM); // Illegal hex constant + state= MY_LEX_CHAR; // Read char by char + break; } - yyGet(); // get_token makes an unget - yylval->lex_str=get_token(lex,length); - yylval->lex_str.str+=2; // Skip x' - yylval->lex_str.length-=3; // Don't count x' and last ' - lex->yytoklen-=3; - return (NCHAR_STRING); + yylval->lex_str.length= lex->yytoklen; + return(NCHAR_STRING); case MY_LEX_IDENT_OR_HEX: if (yyPeek() == '\'') @@ -656,8 +654,9 @@ int MYSQLlex(void *arg, void *yythd) */ if ((yylval->lex_str.str[0]=='_') && - (lex->charset=get_charset_by_csname(yylval->lex_str.str+1, - MY_CS_PRIMARY,MYF(0)))) + (lex->underscore_charset= + get_charset_by_csname(yylval->lex_str.str + 1, + MY_CS_PRIMARY,MYF(0)))) return(UNDERSCORE_CHARSET); return(result_state); // IDENT or IDENT_QUOTED @@ -1055,6 +1054,30 @@ int MYSQLlex(void *arg, void *yythd) } } + +/* + Skip comment in the end of statement. + + SYNOPSIS + skip_rear_comments() + begin pointer to the beginning of statement + end pointer to the end of statement + + DESCRIPTION + The function is intended to trim comments at the end of the statement. + + RETURN + Pointer to the last non-comment symbol of the statement. +*/ + +uchar *skip_rear_comments(uchar *begin, uchar *end) +{ + while (begin < end && (end[-1] <= ' ' || end[-1] == '*' || + end[-1] == '/' || end[-1] == ';')) + end-= 1; + return end; +} + /* st_select_lex structures initialisations */ @@ -1501,10 +1524,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) */ Query_arena *arena= thd->stmt_arena; return (ref_pointer_array= - (Item **)arena->alloc(sizeof(Item*) * - (item_list.elements + - select_n_having_items + - order_group_num)* 5)) == 0; + (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items + + item_list.elements + + select_n_having_items + + order_group_num)*5)) == 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e5b087fc72a..2e19c54cbfe 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -375,7 +375,7 @@ public: friend class st_select_lex_unit; friend bool mysql_new_select(struct st_lex *lex, bool move_down); friend bool mysql_make_view(THD *thd, File_parser *parser, - TABLE_LIST *table); + TABLE_LIST *table, uint flags); private: void fast_exclude(); }; @@ -548,6 +548,12 @@ public: bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ /* TRUE when having fix field called in processing of this SELECT */ bool having_fix_field; + + /* Number of Item_sum-derived objects in this SELECT */ + uint n_sum_items; + /* Number of Item_sum-derived objects in children and descendant SELECTs */ + uint n_child_sum_items; + /* explicit LIMIT clause was used */ bool explicit_limit; /* @@ -640,7 +646,7 @@ public: bool test_limit(); friend void lex_start(THD *thd, uchar *buf, uint length); - st_select_lex() {} + st_select_lex() : n_sum_items(0), n_child_sum_items(0) {} void make_empty_select() { init_query(); @@ -834,7 +840,7 @@ typedef struct st_lex : public Query_tables_list XID *xid; gptr yacc_yyss,yacc_yyvs; THD *thd; - CHARSET_INFO *charset; + CHARSET_INFO *charset, *underscore_charset; /* store original leaf_tables for INSERT SELECT and PS/SP */ TABLE_LIST *leaf_tables_insert; /* Position (first character index) of SELECT of CREATE VIEW statement */ @@ -978,7 +984,7 @@ typedef struct st_lex : public Query_tables_list /* view created to be run from definer (standard behaviour) */ - bool create_view_suid; + uint8 create_view_suid; /* Characterstics of trigger being created */ st_trg_chistics trg_chistics; /* @@ -1115,4 +1121,4 @@ extern void lex_free(void); extern void lex_start(THD *thd, uchar *buf,uint length); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); - +extern uchar *skip_rear_comments(uchar *begin, uchar *end); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 40e1e6b07aa..d5faf6ee7e9 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -147,16 +147,13 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, MYF(0)); DBUG_RETURN(TRUE); } - /* - This needs to be done before external_lock - */ - ha_enable_transaction(thd, FALSE); if (open_and_lock_tables(thd, table_list)) DBUG_RETURN(TRUE); if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context, &thd->lex->select_lex.top_join_list, table_list, &unused_conds, &thd->lex->select_lex.leaf_tables, FALSE, + INSERT_ACL | UPDATE_ACL, INSERT_ACL | UPDATE_ACL)) DBUG_RETURN(-1); if (!table_list->table || // do not suport join view @@ -393,7 +390,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); table->next_number_field=0; } - ha_enable_transaction(thd, TRUE); if (file >= 0) my_close(file,MYF(0)); free_blobs(table); /* if pack_blob was used */ diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc index 9dae55e4508..b947b9dfa98 100644 --- a/sql/sql_locale.cc +++ b/sql/sql_locale.cc @@ -52,8 +52,7 @@ static TYPELIB my_locale_typelib_day_names_ar_AE = { array_elements(my_locale_day_names_ar_AE)-1, "", my_locale_day_names_ar_AE, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ar_AE = { array_elements(my_locale_ab_day_names_ar_AE)-1, "", my_locale_ab_day_names_ar_AE, NULL }; -MY_LOCALE my_locale_ar_AE= - { "ar_AE", "Arabic - United Arab Emirates", FALSE, &my_locale_typelib_month_names_ar_AE, &my_locale_typelib_ab_month_names_ar_AE, &my_locale_typelib_day_names_ar_AE, &my_locale_typelib_ab_day_names_ar_AE }; +MY_LOCALE my_locale_ar_AE ( "ar_AE", "Arabic - United Arab Emirates", FALSE, &my_locale_typelib_month_names_ar_AE, &my_locale_typelib_ab_month_names_ar_AE, &my_locale_typelib_day_names_ar_AE, &my_locale_typelib_ab_day_names_ar_AE ); /***** LOCALE END ar_AE *****/ /***** LOCALE BEGIN ar_BH: Arabic - Bahrain *****/ @@ -73,8 +72,7 @@ static TYPELIB my_locale_typelib_day_names_ar_BH = { array_elements(my_locale_day_names_ar_BH)-1, "", my_locale_day_names_ar_BH, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ar_BH = { array_elements(my_locale_ab_day_names_ar_BH)-1, "", my_locale_ab_day_names_ar_BH, NULL }; -MY_LOCALE my_locale_ar_BH= - { "ar_BH", "Arabic - Bahrain", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_BH ( "ar_BH", "Arabic - Bahrain", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_BH *****/ /***** LOCALE BEGIN ar_JO: Arabic - Jordan *****/ @@ -94,8 +92,7 @@ static TYPELIB my_locale_typelib_day_names_ar_JO = { array_elements(my_locale_day_names_ar_JO)-1, "", my_locale_day_names_ar_JO, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ar_JO = { array_elements(my_locale_ab_day_names_ar_JO)-1, "", my_locale_ab_day_names_ar_JO, NULL }; -MY_LOCALE my_locale_ar_JO= - { "ar_JO", "Arabic - Jordan", FALSE, &my_locale_typelib_month_names_ar_JO, &my_locale_typelib_ab_month_names_ar_JO, &my_locale_typelib_day_names_ar_JO, &my_locale_typelib_ab_day_names_ar_JO }; +MY_LOCALE my_locale_ar_JO ( "ar_JO", "Arabic - Jordan", FALSE, &my_locale_typelib_month_names_ar_JO, &my_locale_typelib_ab_month_names_ar_JO, &my_locale_typelib_day_names_ar_JO, &my_locale_typelib_ab_day_names_ar_JO ); /***** LOCALE END ar_JO *****/ /***** LOCALE BEGIN ar_SA: Arabic - Saudi Arabia *****/ @@ -115,8 +112,7 @@ static TYPELIB my_locale_typelib_day_names_ar_SA = { array_elements(my_locale_day_names_ar_SA)-1, "", my_locale_day_names_ar_SA, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ar_SA = { array_elements(my_locale_ab_day_names_ar_SA)-1, "", my_locale_ab_day_names_ar_SA, NULL }; -MY_LOCALE my_locale_ar_SA= - { "ar_SA", "Arabic - Saudi Arabia", FALSE, &my_locale_typelib_month_names_ar_SA, &my_locale_typelib_ab_month_names_ar_SA, &my_locale_typelib_day_names_ar_SA, &my_locale_typelib_ab_day_names_ar_SA }; +MY_LOCALE my_locale_ar_SA ( "ar_SA", "Arabic - Saudi Arabia", FALSE, &my_locale_typelib_month_names_ar_SA, &my_locale_typelib_ab_month_names_ar_SA, &my_locale_typelib_day_names_ar_SA, &my_locale_typelib_ab_day_names_ar_SA ); /***** LOCALE END ar_SA *****/ /***** LOCALE BEGIN ar_SY: Arabic - Syria *****/ @@ -136,8 +132,7 @@ static TYPELIB my_locale_typelib_day_names_ar_SY = { array_elements(my_locale_day_names_ar_SY)-1, "", my_locale_day_names_ar_SY, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ar_SY = { array_elements(my_locale_ab_day_names_ar_SY)-1, "", my_locale_ab_day_names_ar_SY, NULL }; -MY_LOCALE my_locale_ar_SY= - { "ar_SY", "Arabic - Syria", FALSE, &my_locale_typelib_month_names_ar_SY, &my_locale_typelib_ab_month_names_ar_SY, &my_locale_typelib_day_names_ar_SY, &my_locale_typelib_ab_day_names_ar_SY }; +MY_LOCALE my_locale_ar_SY ( "ar_SY", "Arabic - Syria", FALSE, &my_locale_typelib_month_names_ar_SY, &my_locale_typelib_ab_month_names_ar_SY, &my_locale_typelib_day_names_ar_SY, &my_locale_typelib_ab_day_names_ar_SY ); /***** LOCALE END ar_SY *****/ /***** LOCALE BEGIN be_BY: Belarusian - Belarus *****/ @@ -157,8 +152,7 @@ static TYPELIB my_locale_typelib_day_names_be_BY = { array_elements(my_locale_day_names_be_BY)-1, "", my_locale_day_names_be_BY, NULL }; static TYPELIB my_locale_typelib_ab_day_names_be_BY = { array_elements(my_locale_ab_day_names_be_BY)-1, "", my_locale_ab_day_names_be_BY, NULL }; -MY_LOCALE my_locale_be_BY= - { "be_BY", "Belarusian - Belarus", FALSE, &my_locale_typelib_month_names_be_BY, &my_locale_typelib_ab_month_names_be_BY, &my_locale_typelib_day_names_be_BY, &my_locale_typelib_ab_day_names_be_BY }; +MY_LOCALE my_locale_be_BY ( "be_BY", "Belarusian - Belarus", FALSE, &my_locale_typelib_month_names_be_BY, &my_locale_typelib_ab_month_names_be_BY, &my_locale_typelib_day_names_be_BY, &my_locale_typelib_ab_day_names_be_BY ); /***** LOCALE END be_BY *****/ /***** LOCALE BEGIN bg_BG: Bulgarian - Bulgaria *****/ @@ -178,8 +172,7 @@ static TYPELIB my_locale_typelib_day_names_bg_BG = { array_elements(my_locale_day_names_bg_BG)-1, "", my_locale_day_names_bg_BG, NULL }; static TYPELIB my_locale_typelib_ab_day_names_bg_BG = { array_elements(my_locale_ab_day_names_bg_BG)-1, "", my_locale_ab_day_names_bg_BG, NULL }; -MY_LOCALE my_locale_bg_BG= - { "bg_BG", "Bulgarian - Bulgaria", FALSE, &my_locale_typelib_month_names_bg_BG, &my_locale_typelib_ab_month_names_bg_BG, &my_locale_typelib_day_names_bg_BG, &my_locale_typelib_ab_day_names_bg_BG }; +MY_LOCALE my_locale_bg_BG ( "bg_BG", "Bulgarian - Bulgaria", FALSE, &my_locale_typelib_month_names_bg_BG, &my_locale_typelib_ab_month_names_bg_BG, &my_locale_typelib_day_names_bg_BG, &my_locale_typelib_ab_day_names_bg_BG ); /***** LOCALE END bg_BG *****/ /***** LOCALE BEGIN ca_ES: Catalan - Catalan *****/ @@ -199,8 +192,7 @@ static TYPELIB my_locale_typelib_day_names_ca_ES = { array_elements(my_locale_day_names_ca_ES)-1, "", my_locale_day_names_ca_ES, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ca_ES = { array_elements(my_locale_ab_day_names_ca_ES)-1, "", my_locale_ab_day_names_ca_ES, NULL }; -MY_LOCALE my_locale_ca_ES= - { "ca_ES", "Catalan - Catalan", FALSE, &my_locale_typelib_month_names_ca_ES, &my_locale_typelib_ab_month_names_ca_ES, &my_locale_typelib_day_names_ca_ES, &my_locale_typelib_ab_day_names_ca_ES }; +MY_LOCALE my_locale_ca_ES ( "ca_ES", "Catalan - Catalan", FALSE, &my_locale_typelib_month_names_ca_ES, &my_locale_typelib_ab_month_names_ca_ES, &my_locale_typelib_day_names_ca_ES, &my_locale_typelib_ab_day_names_ca_ES ); /***** LOCALE END ca_ES *****/ /***** LOCALE BEGIN cs_CZ: Czech - Czech Republic *****/ @@ -220,8 +212,7 @@ static TYPELIB my_locale_typelib_day_names_cs_CZ = { array_elements(my_locale_day_names_cs_CZ)-1, "", my_locale_day_names_cs_CZ, NULL }; static TYPELIB my_locale_typelib_ab_day_names_cs_CZ = { array_elements(my_locale_ab_day_names_cs_CZ)-1, "", my_locale_ab_day_names_cs_CZ, NULL }; -MY_LOCALE my_locale_cs_CZ= - { "cs_CZ", "Czech - Czech Republic", FALSE, &my_locale_typelib_month_names_cs_CZ, &my_locale_typelib_ab_month_names_cs_CZ, &my_locale_typelib_day_names_cs_CZ, &my_locale_typelib_ab_day_names_cs_CZ }; +MY_LOCALE my_locale_cs_CZ ( "cs_CZ", "Czech - Czech Republic", FALSE, &my_locale_typelib_month_names_cs_CZ, &my_locale_typelib_ab_month_names_cs_CZ, &my_locale_typelib_day_names_cs_CZ, &my_locale_typelib_ab_day_names_cs_CZ ); /***** LOCALE END cs_CZ *****/ /***** LOCALE BEGIN da_DK: Danish - Denmark *****/ @@ -241,8 +232,7 @@ static TYPELIB my_locale_typelib_day_names_da_DK = { array_elements(my_locale_day_names_da_DK)-1, "", my_locale_day_names_da_DK, NULL }; static TYPELIB my_locale_typelib_ab_day_names_da_DK = { array_elements(my_locale_ab_day_names_da_DK)-1, "", my_locale_ab_day_names_da_DK, NULL }; -MY_LOCALE my_locale_da_DK= - { "da_DK", "Danish - Denmark", FALSE, &my_locale_typelib_month_names_da_DK, &my_locale_typelib_ab_month_names_da_DK, &my_locale_typelib_day_names_da_DK, &my_locale_typelib_ab_day_names_da_DK }; +MY_LOCALE my_locale_da_DK ( "da_DK", "Danish - Denmark", FALSE, &my_locale_typelib_month_names_da_DK, &my_locale_typelib_ab_month_names_da_DK, &my_locale_typelib_day_names_da_DK, &my_locale_typelib_ab_day_names_da_DK ); /***** LOCALE END da_DK *****/ /***** LOCALE BEGIN de_AT: German - Austria *****/ @@ -262,8 +252,7 @@ static TYPELIB my_locale_typelib_day_names_de_AT = { array_elements(my_locale_day_names_de_AT)-1, "", my_locale_day_names_de_AT, NULL }; static TYPELIB my_locale_typelib_ab_day_names_de_AT = { array_elements(my_locale_ab_day_names_de_AT)-1, "", my_locale_ab_day_names_de_AT, NULL }; -MY_LOCALE my_locale_de_AT= - { "de_AT", "German - Austria", FALSE, &my_locale_typelib_month_names_de_AT, &my_locale_typelib_ab_month_names_de_AT, &my_locale_typelib_day_names_de_AT, &my_locale_typelib_ab_day_names_de_AT }; +MY_LOCALE my_locale_de_AT ( "de_AT", "German - Austria", FALSE, &my_locale_typelib_month_names_de_AT, &my_locale_typelib_ab_month_names_de_AT, &my_locale_typelib_day_names_de_AT, &my_locale_typelib_ab_day_names_de_AT ); /***** LOCALE END de_AT *****/ /***** LOCALE BEGIN de_DE: German - Germany *****/ @@ -283,8 +272,7 @@ static TYPELIB my_locale_typelib_day_names_de_DE = { array_elements(my_locale_day_names_de_DE)-1, "", my_locale_day_names_de_DE, NULL }; static TYPELIB my_locale_typelib_ab_day_names_de_DE = { array_elements(my_locale_ab_day_names_de_DE)-1, "", my_locale_ab_day_names_de_DE, NULL }; -MY_LOCALE my_locale_de_DE= - { "de_DE", "German - Germany", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE }; +MY_LOCALE my_locale_de_DE ( "de_DE", "German - Germany", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE ); /***** LOCALE END de_DE *****/ /***** LOCALE BEGIN en_US: English - United States *****/ @@ -304,8 +292,7 @@ static TYPELIB my_locale_typelib_day_names_en_US = { array_elements(my_locale_day_names_en_US)-1, "", my_locale_day_names_en_US, NULL }; static TYPELIB my_locale_typelib_ab_day_names_en_US = { array_elements(my_locale_ab_day_names_en_US)-1, "", my_locale_ab_day_names_en_US, NULL }; -MY_LOCALE my_locale_en_US= - { "en_US", "English - United States", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_US ( "en_US", "English - United States", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_US *****/ /***** LOCALE BEGIN es_ES: Spanish - Spain *****/ @@ -325,8 +312,7 @@ static TYPELIB my_locale_typelib_day_names_es_ES = { array_elements(my_locale_day_names_es_ES)-1, "", my_locale_day_names_es_ES, NULL }; static TYPELIB my_locale_typelib_ab_day_names_es_ES = { array_elements(my_locale_ab_day_names_es_ES)-1, "", my_locale_ab_day_names_es_ES, NULL }; -MY_LOCALE my_locale_es_ES= - { "es_ES", "Spanish - Spain", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_ES ( "es_ES", "Spanish - Spain", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_ES *****/ /***** LOCALE BEGIN et_EE: Estonian - Estonia *****/ @@ -346,8 +332,7 @@ static TYPELIB my_locale_typelib_day_names_et_EE = { array_elements(my_locale_day_names_et_EE)-1, "", my_locale_day_names_et_EE, NULL }; static TYPELIB my_locale_typelib_ab_day_names_et_EE = { array_elements(my_locale_ab_day_names_et_EE)-1, "", my_locale_ab_day_names_et_EE, NULL }; -MY_LOCALE my_locale_et_EE= - { "et_EE", "Estonian - Estonia", FALSE, &my_locale_typelib_month_names_et_EE, &my_locale_typelib_ab_month_names_et_EE, &my_locale_typelib_day_names_et_EE, &my_locale_typelib_ab_day_names_et_EE }; +MY_LOCALE my_locale_et_EE ( "et_EE", "Estonian - Estonia", FALSE, &my_locale_typelib_month_names_et_EE, &my_locale_typelib_ab_month_names_et_EE, &my_locale_typelib_day_names_et_EE, &my_locale_typelib_ab_day_names_et_EE ); /***** LOCALE END et_EE *****/ /***** LOCALE BEGIN eu_ES: Basque - Basque *****/ @@ -367,8 +352,7 @@ static TYPELIB my_locale_typelib_day_names_eu_ES = { array_elements(my_locale_day_names_eu_ES)-1, "", my_locale_day_names_eu_ES, NULL }; static TYPELIB my_locale_typelib_ab_day_names_eu_ES = { array_elements(my_locale_ab_day_names_eu_ES)-1, "", my_locale_ab_day_names_eu_ES, NULL }; -MY_LOCALE my_locale_eu_ES= - { "eu_ES", "Basque - Basque", TRUE, &my_locale_typelib_month_names_eu_ES, &my_locale_typelib_ab_month_names_eu_ES, &my_locale_typelib_day_names_eu_ES, &my_locale_typelib_ab_day_names_eu_ES }; +MY_LOCALE my_locale_eu_ES ( "eu_ES", "Basque - Basque", TRUE, &my_locale_typelib_month_names_eu_ES, &my_locale_typelib_ab_month_names_eu_ES, &my_locale_typelib_day_names_eu_ES, &my_locale_typelib_ab_day_names_eu_ES ); /***** LOCALE END eu_ES *****/ /***** LOCALE BEGIN fi_FI: Finnish - Finland *****/ @@ -388,8 +372,7 @@ static TYPELIB my_locale_typelib_day_names_fi_FI = { array_elements(my_locale_day_names_fi_FI)-1, "", my_locale_day_names_fi_FI, NULL }; static TYPELIB my_locale_typelib_ab_day_names_fi_FI = { array_elements(my_locale_ab_day_names_fi_FI)-1, "", my_locale_ab_day_names_fi_FI, NULL }; -MY_LOCALE my_locale_fi_FI= - { "fi_FI", "Finnish - Finland", FALSE, &my_locale_typelib_month_names_fi_FI, &my_locale_typelib_ab_month_names_fi_FI, &my_locale_typelib_day_names_fi_FI, &my_locale_typelib_ab_day_names_fi_FI }; +MY_LOCALE my_locale_fi_FI ( "fi_FI", "Finnish - Finland", FALSE, &my_locale_typelib_month_names_fi_FI, &my_locale_typelib_ab_month_names_fi_FI, &my_locale_typelib_day_names_fi_FI, &my_locale_typelib_ab_day_names_fi_FI ); /***** LOCALE END fi_FI *****/ /***** LOCALE BEGIN fo_FO: Faroese - Faroe Islands *****/ @@ -409,8 +392,7 @@ static TYPELIB my_locale_typelib_day_names_fo_FO = { array_elements(my_locale_day_names_fo_FO)-1, "", my_locale_day_names_fo_FO, NULL }; static TYPELIB my_locale_typelib_ab_day_names_fo_FO = { array_elements(my_locale_ab_day_names_fo_FO)-1, "", my_locale_ab_day_names_fo_FO, NULL }; -MY_LOCALE my_locale_fo_FO= - { "fo_FO", "Faroese - Faroe Islands", FALSE, &my_locale_typelib_month_names_fo_FO, &my_locale_typelib_ab_month_names_fo_FO, &my_locale_typelib_day_names_fo_FO, &my_locale_typelib_ab_day_names_fo_FO }; +MY_LOCALE my_locale_fo_FO ( "fo_FO", "Faroese - Faroe Islands", FALSE, &my_locale_typelib_month_names_fo_FO, &my_locale_typelib_ab_month_names_fo_FO, &my_locale_typelib_day_names_fo_FO, &my_locale_typelib_ab_day_names_fo_FO ); /***** LOCALE END fo_FO *****/ /***** LOCALE BEGIN fr_FR: French - France *****/ @@ -430,8 +412,7 @@ static TYPELIB my_locale_typelib_day_names_fr_FR = { array_elements(my_locale_day_names_fr_FR)-1, "", my_locale_day_names_fr_FR, NULL }; static TYPELIB my_locale_typelib_ab_day_names_fr_FR = { array_elements(my_locale_ab_day_names_fr_FR)-1, "", my_locale_ab_day_names_fr_FR, NULL }; -MY_LOCALE my_locale_fr_FR= - { "fr_FR", "French - France", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR }; +MY_LOCALE my_locale_fr_FR ( "fr_FR", "French - France", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR ); /***** LOCALE END fr_FR *****/ /***** LOCALE BEGIN gl_ES: Galician - Galician *****/ @@ -451,8 +432,7 @@ static TYPELIB my_locale_typelib_day_names_gl_ES = { array_elements(my_locale_day_names_gl_ES)-1, "", my_locale_day_names_gl_ES, NULL }; static TYPELIB my_locale_typelib_ab_day_names_gl_ES = { array_elements(my_locale_ab_day_names_gl_ES)-1, "", my_locale_ab_day_names_gl_ES, NULL }; -MY_LOCALE my_locale_gl_ES= - { "gl_ES", "Galician - Galician", FALSE, &my_locale_typelib_month_names_gl_ES, &my_locale_typelib_ab_month_names_gl_ES, &my_locale_typelib_day_names_gl_ES, &my_locale_typelib_ab_day_names_gl_ES }; +MY_LOCALE my_locale_gl_ES ( "gl_ES", "Galician - Galician", FALSE, &my_locale_typelib_month_names_gl_ES, &my_locale_typelib_ab_month_names_gl_ES, &my_locale_typelib_day_names_gl_ES, &my_locale_typelib_ab_day_names_gl_ES ); /***** LOCALE END gl_ES *****/ /***** LOCALE BEGIN gu_IN: Gujarati - India *****/ @@ -472,8 +452,7 @@ static TYPELIB my_locale_typelib_day_names_gu_IN = { array_elements(my_locale_day_names_gu_IN)-1, "", my_locale_day_names_gu_IN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_gu_IN = { array_elements(my_locale_ab_day_names_gu_IN)-1, "", my_locale_ab_day_names_gu_IN, NULL }; -MY_LOCALE my_locale_gu_IN= - { "gu_IN", "Gujarati - India", FALSE, &my_locale_typelib_month_names_gu_IN, &my_locale_typelib_ab_month_names_gu_IN, &my_locale_typelib_day_names_gu_IN, &my_locale_typelib_ab_day_names_gu_IN }; +MY_LOCALE my_locale_gu_IN ( "gu_IN", "Gujarati - India", FALSE, &my_locale_typelib_month_names_gu_IN, &my_locale_typelib_ab_month_names_gu_IN, &my_locale_typelib_day_names_gu_IN, &my_locale_typelib_ab_day_names_gu_IN ); /***** LOCALE END gu_IN *****/ /***** LOCALE BEGIN he_IL: Hebrew - Israel *****/ @@ -493,8 +472,7 @@ static TYPELIB my_locale_typelib_day_names_he_IL = { array_elements(my_locale_day_names_he_IL)-1, "", my_locale_day_names_he_IL, NULL }; static TYPELIB my_locale_typelib_ab_day_names_he_IL = { array_elements(my_locale_ab_day_names_he_IL)-1, "", my_locale_ab_day_names_he_IL, NULL }; -MY_LOCALE my_locale_he_IL= - { "he_IL", "Hebrew - Israel", FALSE, &my_locale_typelib_month_names_he_IL, &my_locale_typelib_ab_month_names_he_IL, &my_locale_typelib_day_names_he_IL, &my_locale_typelib_ab_day_names_he_IL }; +MY_LOCALE my_locale_he_IL ( "he_IL", "Hebrew - Israel", FALSE, &my_locale_typelib_month_names_he_IL, &my_locale_typelib_ab_month_names_he_IL, &my_locale_typelib_day_names_he_IL, &my_locale_typelib_ab_day_names_he_IL ); /***** LOCALE END he_IL *****/ /***** LOCALE BEGIN hi_IN: Hindi - India *****/ @@ -514,8 +492,7 @@ static TYPELIB my_locale_typelib_day_names_hi_IN = { array_elements(my_locale_day_names_hi_IN)-1, "", my_locale_day_names_hi_IN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_hi_IN = { array_elements(my_locale_ab_day_names_hi_IN)-1, "", my_locale_ab_day_names_hi_IN, NULL }; -MY_LOCALE my_locale_hi_IN= - { "hi_IN", "Hindi - India", FALSE, &my_locale_typelib_month_names_hi_IN, &my_locale_typelib_ab_month_names_hi_IN, &my_locale_typelib_day_names_hi_IN, &my_locale_typelib_ab_day_names_hi_IN }; +MY_LOCALE my_locale_hi_IN ( "hi_IN", "Hindi - India", FALSE, &my_locale_typelib_month_names_hi_IN, &my_locale_typelib_ab_month_names_hi_IN, &my_locale_typelib_day_names_hi_IN, &my_locale_typelib_ab_day_names_hi_IN ); /***** LOCALE END hi_IN *****/ /***** LOCALE BEGIN hr_HR: Croatian - Croatia *****/ @@ -535,8 +512,7 @@ static TYPELIB my_locale_typelib_day_names_hr_HR = { array_elements(my_locale_day_names_hr_HR)-1, "", my_locale_day_names_hr_HR, NULL }; static TYPELIB my_locale_typelib_ab_day_names_hr_HR = { array_elements(my_locale_ab_day_names_hr_HR)-1, "", my_locale_ab_day_names_hr_HR, NULL }; -MY_LOCALE my_locale_hr_HR= - { "hr_HR", "Croatian - Croatia", FALSE, &my_locale_typelib_month_names_hr_HR, &my_locale_typelib_ab_month_names_hr_HR, &my_locale_typelib_day_names_hr_HR, &my_locale_typelib_ab_day_names_hr_HR }; +MY_LOCALE my_locale_hr_HR ( "hr_HR", "Croatian - Croatia", FALSE, &my_locale_typelib_month_names_hr_HR, &my_locale_typelib_ab_month_names_hr_HR, &my_locale_typelib_day_names_hr_HR, &my_locale_typelib_ab_day_names_hr_HR ); /***** LOCALE END hr_HR *****/ /***** LOCALE BEGIN hu_HU: Hungarian - Hungary *****/ @@ -556,8 +532,7 @@ static TYPELIB my_locale_typelib_day_names_hu_HU = { array_elements(my_locale_day_names_hu_HU)-1, "", my_locale_day_names_hu_HU, NULL }; static TYPELIB my_locale_typelib_ab_day_names_hu_HU = { array_elements(my_locale_ab_day_names_hu_HU)-1, "", my_locale_ab_day_names_hu_HU, NULL }; -MY_LOCALE my_locale_hu_HU= - { "hu_HU", "Hungarian - Hungary", FALSE, &my_locale_typelib_month_names_hu_HU, &my_locale_typelib_ab_month_names_hu_HU, &my_locale_typelib_day_names_hu_HU, &my_locale_typelib_ab_day_names_hu_HU }; +MY_LOCALE my_locale_hu_HU ( "hu_HU", "Hungarian - Hungary", FALSE, &my_locale_typelib_month_names_hu_HU, &my_locale_typelib_ab_month_names_hu_HU, &my_locale_typelib_day_names_hu_HU, &my_locale_typelib_ab_day_names_hu_HU ); /***** LOCALE END hu_HU *****/ /***** LOCALE BEGIN id_ID: Indonesian - Indonesia *****/ @@ -577,8 +552,7 @@ static TYPELIB my_locale_typelib_day_names_id_ID = { array_elements(my_locale_day_names_id_ID)-1, "", my_locale_day_names_id_ID, NULL }; static TYPELIB my_locale_typelib_ab_day_names_id_ID = { array_elements(my_locale_ab_day_names_id_ID)-1, "", my_locale_ab_day_names_id_ID, NULL }; -MY_LOCALE my_locale_id_ID= - { "id_ID", "Indonesian - Indonesia", TRUE, &my_locale_typelib_month_names_id_ID, &my_locale_typelib_ab_month_names_id_ID, &my_locale_typelib_day_names_id_ID, &my_locale_typelib_ab_day_names_id_ID }; +MY_LOCALE my_locale_id_ID ( "id_ID", "Indonesian - Indonesia", TRUE, &my_locale_typelib_month_names_id_ID, &my_locale_typelib_ab_month_names_id_ID, &my_locale_typelib_day_names_id_ID, &my_locale_typelib_ab_day_names_id_ID ); /***** LOCALE END id_ID *****/ /***** LOCALE BEGIN is_IS: Icelandic - Iceland *****/ @@ -598,8 +572,7 @@ static TYPELIB my_locale_typelib_day_names_is_IS = { array_elements(my_locale_day_names_is_IS)-1, "", my_locale_day_names_is_IS, NULL }; static TYPELIB my_locale_typelib_ab_day_names_is_IS = { array_elements(my_locale_ab_day_names_is_IS)-1, "", my_locale_ab_day_names_is_IS, NULL }; -MY_LOCALE my_locale_is_IS= - { "is_IS", "Icelandic - Iceland", FALSE, &my_locale_typelib_month_names_is_IS, &my_locale_typelib_ab_month_names_is_IS, &my_locale_typelib_day_names_is_IS, &my_locale_typelib_ab_day_names_is_IS }; +MY_LOCALE my_locale_is_IS ( "is_IS", "Icelandic - Iceland", FALSE, &my_locale_typelib_month_names_is_IS, &my_locale_typelib_ab_month_names_is_IS, &my_locale_typelib_day_names_is_IS, &my_locale_typelib_ab_day_names_is_IS ); /***** LOCALE END is_IS *****/ /***** LOCALE BEGIN it_CH: Italian - Switzerland *****/ @@ -619,8 +592,7 @@ static TYPELIB my_locale_typelib_day_names_it_CH = { array_elements(my_locale_day_names_it_CH)-1, "", my_locale_day_names_it_CH, NULL }; static TYPELIB my_locale_typelib_ab_day_names_it_CH = { array_elements(my_locale_ab_day_names_it_CH)-1, "", my_locale_ab_day_names_it_CH, NULL }; -MY_LOCALE my_locale_it_CH= - { "it_CH", "Italian - Switzerland", FALSE, &my_locale_typelib_month_names_it_CH, &my_locale_typelib_ab_month_names_it_CH, &my_locale_typelib_day_names_it_CH, &my_locale_typelib_ab_day_names_it_CH }; +MY_LOCALE my_locale_it_CH ( "it_CH", "Italian - Switzerland", FALSE, &my_locale_typelib_month_names_it_CH, &my_locale_typelib_ab_month_names_it_CH, &my_locale_typelib_day_names_it_CH, &my_locale_typelib_ab_day_names_it_CH ); /***** LOCALE END it_CH *****/ /***** LOCALE BEGIN ja_JP: Japanese - Japan *****/ @@ -640,8 +612,7 @@ static TYPELIB my_locale_typelib_day_names_ja_JP = { array_elements(my_locale_day_names_ja_JP)-1, "", my_locale_day_names_ja_JP, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ja_JP = { array_elements(my_locale_ab_day_names_ja_JP)-1, "", my_locale_ab_day_names_ja_JP, NULL }; -MY_LOCALE my_locale_ja_JP= - { "ja_JP", "Japanese - Japan", FALSE, &my_locale_typelib_month_names_ja_JP, &my_locale_typelib_ab_month_names_ja_JP, &my_locale_typelib_day_names_ja_JP, &my_locale_typelib_ab_day_names_ja_JP }; +MY_LOCALE my_locale_ja_JP ( "ja_JP", "Japanese - Japan", FALSE, &my_locale_typelib_month_names_ja_JP, &my_locale_typelib_ab_month_names_ja_JP, &my_locale_typelib_day_names_ja_JP, &my_locale_typelib_ab_day_names_ja_JP ); /***** LOCALE END ja_JP *****/ /***** LOCALE BEGIN ko_KR: Korean - Korea *****/ @@ -661,8 +632,7 @@ static TYPELIB my_locale_typelib_day_names_ko_KR = { array_elements(my_locale_day_names_ko_KR)-1, "", my_locale_day_names_ko_KR, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ko_KR = { array_elements(my_locale_ab_day_names_ko_KR)-1, "", my_locale_ab_day_names_ko_KR, NULL }; -MY_LOCALE my_locale_ko_KR= - { "ko_KR", "Korean - Korea", FALSE, &my_locale_typelib_month_names_ko_KR, &my_locale_typelib_ab_month_names_ko_KR, &my_locale_typelib_day_names_ko_KR, &my_locale_typelib_ab_day_names_ko_KR }; +MY_LOCALE my_locale_ko_KR ( "ko_KR", "Korean - Korea", FALSE, &my_locale_typelib_month_names_ko_KR, &my_locale_typelib_ab_month_names_ko_KR, &my_locale_typelib_day_names_ko_KR, &my_locale_typelib_ab_day_names_ko_KR ); /***** LOCALE END ko_KR *****/ /***** LOCALE BEGIN lt_LT: Lithuanian - Lithuania *****/ @@ -682,8 +652,7 @@ static TYPELIB my_locale_typelib_day_names_lt_LT = { array_elements(my_locale_day_names_lt_LT)-1, "", my_locale_day_names_lt_LT, NULL }; static TYPELIB my_locale_typelib_ab_day_names_lt_LT = { array_elements(my_locale_ab_day_names_lt_LT)-1, "", my_locale_ab_day_names_lt_LT, NULL }; -MY_LOCALE my_locale_lt_LT= - { "lt_LT", "Lithuanian - Lithuania", FALSE, &my_locale_typelib_month_names_lt_LT, &my_locale_typelib_ab_month_names_lt_LT, &my_locale_typelib_day_names_lt_LT, &my_locale_typelib_ab_day_names_lt_LT }; +MY_LOCALE my_locale_lt_LT ( "lt_LT", "Lithuanian - Lithuania", FALSE, &my_locale_typelib_month_names_lt_LT, &my_locale_typelib_ab_month_names_lt_LT, &my_locale_typelib_day_names_lt_LT, &my_locale_typelib_ab_day_names_lt_LT ); /***** LOCALE END lt_LT *****/ /***** LOCALE BEGIN lv_LV: Latvian - Latvia *****/ @@ -703,8 +672,7 @@ static TYPELIB my_locale_typelib_day_names_lv_LV = { array_elements(my_locale_day_names_lv_LV)-1, "", my_locale_day_names_lv_LV, NULL }; static TYPELIB my_locale_typelib_ab_day_names_lv_LV = { array_elements(my_locale_ab_day_names_lv_LV)-1, "", my_locale_ab_day_names_lv_LV, NULL }; -MY_LOCALE my_locale_lv_LV= - { "lv_LV", "Latvian - Latvia", FALSE, &my_locale_typelib_month_names_lv_LV, &my_locale_typelib_ab_month_names_lv_LV, &my_locale_typelib_day_names_lv_LV, &my_locale_typelib_ab_day_names_lv_LV }; +MY_LOCALE my_locale_lv_LV ( "lv_LV", "Latvian - Latvia", FALSE, &my_locale_typelib_month_names_lv_LV, &my_locale_typelib_ab_month_names_lv_LV, &my_locale_typelib_day_names_lv_LV, &my_locale_typelib_ab_day_names_lv_LV ); /***** LOCALE END lv_LV *****/ /***** LOCALE BEGIN mk_MK: Macedonian - FYROM *****/ @@ -724,8 +692,7 @@ static TYPELIB my_locale_typelib_day_names_mk_MK = { array_elements(my_locale_day_names_mk_MK)-1, "", my_locale_day_names_mk_MK, NULL }; static TYPELIB my_locale_typelib_ab_day_names_mk_MK = { array_elements(my_locale_ab_day_names_mk_MK)-1, "", my_locale_ab_day_names_mk_MK, NULL }; -MY_LOCALE my_locale_mk_MK= - { "mk_MK", "Macedonian - FYROM", FALSE, &my_locale_typelib_month_names_mk_MK, &my_locale_typelib_ab_month_names_mk_MK, &my_locale_typelib_day_names_mk_MK, &my_locale_typelib_ab_day_names_mk_MK }; +MY_LOCALE my_locale_mk_MK ( "mk_MK", "Macedonian - FYROM", FALSE, &my_locale_typelib_month_names_mk_MK, &my_locale_typelib_ab_month_names_mk_MK, &my_locale_typelib_day_names_mk_MK, &my_locale_typelib_ab_day_names_mk_MK ); /***** LOCALE END mk_MK *****/ /***** LOCALE BEGIN mn_MN: Mongolia - Mongolian *****/ @@ -745,8 +712,7 @@ static TYPELIB my_locale_typelib_day_names_mn_MN = { array_elements(my_locale_day_names_mn_MN)-1, "", my_locale_day_names_mn_MN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_mn_MN = { array_elements(my_locale_ab_day_names_mn_MN)-1, "", my_locale_ab_day_names_mn_MN, NULL }; -MY_LOCALE my_locale_mn_MN= - { "mn_MN", "Mongolia - Mongolian", FALSE, &my_locale_typelib_month_names_mn_MN, &my_locale_typelib_ab_month_names_mn_MN, &my_locale_typelib_day_names_mn_MN, &my_locale_typelib_ab_day_names_mn_MN }; +MY_LOCALE my_locale_mn_MN ( "mn_MN", "Mongolia - Mongolian", FALSE, &my_locale_typelib_month_names_mn_MN, &my_locale_typelib_ab_month_names_mn_MN, &my_locale_typelib_day_names_mn_MN, &my_locale_typelib_ab_day_names_mn_MN ); /***** LOCALE END mn_MN *****/ /***** LOCALE BEGIN ms_MY: Malay - Malaysia *****/ @@ -766,8 +732,7 @@ static TYPELIB my_locale_typelib_day_names_ms_MY = { array_elements(my_locale_day_names_ms_MY)-1, "", my_locale_day_names_ms_MY, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ms_MY = { array_elements(my_locale_ab_day_names_ms_MY)-1, "", my_locale_ab_day_names_ms_MY, NULL }; -MY_LOCALE my_locale_ms_MY= - { "ms_MY", "Malay - Malaysia", TRUE, &my_locale_typelib_month_names_ms_MY, &my_locale_typelib_ab_month_names_ms_MY, &my_locale_typelib_day_names_ms_MY, &my_locale_typelib_ab_day_names_ms_MY }; +MY_LOCALE my_locale_ms_MY ( "ms_MY", "Malay - Malaysia", TRUE, &my_locale_typelib_month_names_ms_MY, &my_locale_typelib_ab_month_names_ms_MY, &my_locale_typelib_day_names_ms_MY, &my_locale_typelib_ab_day_names_ms_MY ); /***** LOCALE END ms_MY *****/ /***** LOCALE BEGIN nb_NO: Norwegian(Bokml) - Norway *****/ @@ -787,8 +752,7 @@ static TYPELIB my_locale_typelib_day_names_nb_NO = { array_elements(my_locale_day_names_nb_NO)-1, "", my_locale_day_names_nb_NO, NULL }; static TYPELIB my_locale_typelib_ab_day_names_nb_NO = { array_elements(my_locale_ab_day_names_nb_NO)-1, "", my_locale_ab_day_names_nb_NO, NULL }; -MY_LOCALE my_locale_nb_NO= - { "nb_NO", "Norwegian(Bokml) - Norway", FALSE, &my_locale_typelib_month_names_nb_NO, &my_locale_typelib_ab_month_names_nb_NO, &my_locale_typelib_day_names_nb_NO, &my_locale_typelib_ab_day_names_nb_NO }; +MY_LOCALE my_locale_nb_NO ( "nb_NO", "Norwegian(Bokml) - Norway", FALSE, &my_locale_typelib_month_names_nb_NO, &my_locale_typelib_ab_month_names_nb_NO, &my_locale_typelib_day_names_nb_NO, &my_locale_typelib_ab_day_names_nb_NO ); /***** LOCALE END nb_NO *****/ /***** LOCALE BEGIN nl_NL: Dutch - The Netherlands *****/ @@ -808,8 +772,7 @@ static TYPELIB my_locale_typelib_day_names_nl_NL = { array_elements(my_locale_day_names_nl_NL)-1, "", my_locale_day_names_nl_NL, NULL }; static TYPELIB my_locale_typelib_ab_day_names_nl_NL = { array_elements(my_locale_ab_day_names_nl_NL)-1, "", my_locale_ab_day_names_nl_NL, NULL }; -MY_LOCALE my_locale_nl_NL= - { "nl_NL", "Dutch - The Netherlands", TRUE, &my_locale_typelib_month_names_nl_NL, &my_locale_typelib_ab_month_names_nl_NL, &my_locale_typelib_day_names_nl_NL, &my_locale_typelib_ab_day_names_nl_NL }; +MY_LOCALE my_locale_nl_NL ( "nl_NL", "Dutch - The Netherlands", TRUE, &my_locale_typelib_month_names_nl_NL, &my_locale_typelib_ab_month_names_nl_NL, &my_locale_typelib_day_names_nl_NL, &my_locale_typelib_ab_day_names_nl_NL ); /***** LOCALE END nl_NL *****/ /***** LOCALE BEGIN pl_PL: Polish - Poland *****/ @@ -829,8 +792,7 @@ static TYPELIB my_locale_typelib_day_names_pl_PL = { array_elements(my_locale_day_names_pl_PL)-1, "", my_locale_day_names_pl_PL, NULL }; static TYPELIB my_locale_typelib_ab_day_names_pl_PL = { array_elements(my_locale_ab_day_names_pl_PL)-1, "", my_locale_ab_day_names_pl_PL, NULL }; -MY_LOCALE my_locale_pl_PL= - { "pl_PL", "Polish - Poland", FALSE, &my_locale_typelib_month_names_pl_PL, &my_locale_typelib_ab_month_names_pl_PL, &my_locale_typelib_day_names_pl_PL, &my_locale_typelib_ab_day_names_pl_PL }; +MY_LOCALE my_locale_pl_PL ( "pl_PL", "Polish - Poland", FALSE, &my_locale_typelib_month_names_pl_PL, &my_locale_typelib_ab_month_names_pl_PL, &my_locale_typelib_day_names_pl_PL, &my_locale_typelib_ab_day_names_pl_PL ); /***** LOCALE END pl_PL *****/ /***** LOCALE BEGIN pt_BR: Portugese - Brazil *****/ @@ -850,8 +812,7 @@ static TYPELIB my_locale_typelib_day_names_pt_BR = { array_elements(my_locale_day_names_pt_BR)-1, "", my_locale_day_names_pt_BR, NULL }; static TYPELIB my_locale_typelib_ab_day_names_pt_BR = { array_elements(my_locale_ab_day_names_pt_BR)-1, "", my_locale_ab_day_names_pt_BR, NULL }; -MY_LOCALE my_locale_pt_BR= - { "pt_BR", "Portugese - Brazil", FALSE, &my_locale_typelib_month_names_pt_BR, &my_locale_typelib_ab_month_names_pt_BR, &my_locale_typelib_day_names_pt_BR, &my_locale_typelib_ab_day_names_pt_BR }; +MY_LOCALE my_locale_pt_BR ( "pt_BR", "Portugese - Brazil", FALSE, &my_locale_typelib_month_names_pt_BR, &my_locale_typelib_ab_month_names_pt_BR, &my_locale_typelib_day_names_pt_BR, &my_locale_typelib_ab_day_names_pt_BR ); /***** LOCALE END pt_BR *****/ /***** LOCALE BEGIN pt_PT: Portugese - Portugal *****/ @@ -871,8 +832,7 @@ static TYPELIB my_locale_typelib_day_names_pt_PT = { array_elements(my_locale_day_names_pt_PT)-1, "", my_locale_day_names_pt_PT, NULL }; static TYPELIB my_locale_typelib_ab_day_names_pt_PT = { array_elements(my_locale_ab_day_names_pt_PT)-1, "", my_locale_ab_day_names_pt_PT, NULL }; -MY_LOCALE my_locale_pt_PT= - { "pt_PT", "Portugese - Portugal", FALSE, &my_locale_typelib_month_names_pt_PT, &my_locale_typelib_ab_month_names_pt_PT, &my_locale_typelib_day_names_pt_PT, &my_locale_typelib_ab_day_names_pt_PT }; +MY_LOCALE my_locale_pt_PT ( "pt_PT", "Portugese - Portugal", FALSE, &my_locale_typelib_month_names_pt_PT, &my_locale_typelib_ab_month_names_pt_PT, &my_locale_typelib_day_names_pt_PT, &my_locale_typelib_ab_day_names_pt_PT ); /***** LOCALE END pt_PT *****/ /***** LOCALE BEGIN ro_RO: Romanian - Romania *****/ @@ -892,8 +852,7 @@ static TYPELIB my_locale_typelib_day_names_ro_RO = { array_elements(my_locale_day_names_ro_RO)-1, "", my_locale_day_names_ro_RO, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ro_RO = { array_elements(my_locale_ab_day_names_ro_RO)-1, "", my_locale_ab_day_names_ro_RO, NULL }; -MY_LOCALE my_locale_ro_RO= - { "ro_RO", "Romanian - Romania", FALSE, &my_locale_typelib_month_names_ro_RO, &my_locale_typelib_ab_month_names_ro_RO, &my_locale_typelib_day_names_ro_RO, &my_locale_typelib_ab_day_names_ro_RO }; +MY_LOCALE my_locale_ro_RO ( "ro_RO", "Romanian - Romania", FALSE, &my_locale_typelib_month_names_ro_RO, &my_locale_typelib_ab_month_names_ro_RO, &my_locale_typelib_day_names_ro_RO, &my_locale_typelib_ab_day_names_ro_RO ); /***** LOCALE END ro_RO *****/ /***** LOCALE BEGIN ru_RU: Russian - Russia *****/ @@ -913,8 +872,7 @@ static TYPELIB my_locale_typelib_day_names_ru_RU = { array_elements(my_locale_day_names_ru_RU)-1, "", my_locale_day_names_ru_RU, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ru_RU = { array_elements(my_locale_ab_day_names_ru_RU)-1, "", my_locale_ab_day_names_ru_RU, NULL }; -MY_LOCALE my_locale_ru_RU= - { "ru_RU", "Russian - Russia", FALSE, &my_locale_typelib_month_names_ru_RU, &my_locale_typelib_ab_month_names_ru_RU, &my_locale_typelib_day_names_ru_RU, &my_locale_typelib_ab_day_names_ru_RU }; +MY_LOCALE my_locale_ru_RU ( "ru_RU", "Russian - Russia", FALSE, &my_locale_typelib_month_names_ru_RU, &my_locale_typelib_ab_month_names_ru_RU, &my_locale_typelib_day_names_ru_RU, &my_locale_typelib_ab_day_names_ru_RU ); /***** LOCALE END ru_RU *****/ /***** LOCALE BEGIN ru_UA: Russian - Ukraine *****/ @@ -934,8 +892,7 @@ static TYPELIB my_locale_typelib_day_names_ru_UA = { array_elements(my_locale_day_names_ru_UA)-1, "", my_locale_day_names_ru_UA, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ru_UA = { array_elements(my_locale_ab_day_names_ru_UA)-1, "", my_locale_ab_day_names_ru_UA, NULL }; -MY_LOCALE my_locale_ru_UA= - { "ru_UA", "Russian - Ukraine", FALSE, &my_locale_typelib_month_names_ru_UA, &my_locale_typelib_ab_month_names_ru_UA, &my_locale_typelib_day_names_ru_UA, &my_locale_typelib_ab_day_names_ru_UA }; +MY_LOCALE my_locale_ru_UA ( "ru_UA", "Russian - Ukraine", FALSE, &my_locale_typelib_month_names_ru_UA, &my_locale_typelib_ab_month_names_ru_UA, &my_locale_typelib_day_names_ru_UA, &my_locale_typelib_ab_day_names_ru_UA ); /***** LOCALE END ru_UA *****/ /***** LOCALE BEGIN sk_SK: Slovak - Slovakia *****/ @@ -955,8 +912,7 @@ static TYPELIB my_locale_typelib_day_names_sk_SK = { array_elements(my_locale_day_names_sk_SK)-1, "", my_locale_day_names_sk_SK, NULL }; static TYPELIB my_locale_typelib_ab_day_names_sk_SK = { array_elements(my_locale_ab_day_names_sk_SK)-1, "", my_locale_ab_day_names_sk_SK, NULL }; -MY_LOCALE my_locale_sk_SK= - { "sk_SK", "Slovak - Slovakia", FALSE, &my_locale_typelib_month_names_sk_SK, &my_locale_typelib_ab_month_names_sk_SK, &my_locale_typelib_day_names_sk_SK, &my_locale_typelib_ab_day_names_sk_SK }; +MY_LOCALE my_locale_sk_SK ( "sk_SK", "Slovak - Slovakia", FALSE, &my_locale_typelib_month_names_sk_SK, &my_locale_typelib_ab_month_names_sk_SK, &my_locale_typelib_day_names_sk_SK, &my_locale_typelib_ab_day_names_sk_SK ); /***** LOCALE END sk_SK *****/ /***** LOCALE BEGIN sl_SI: Slovenian - Slovenia *****/ @@ -976,8 +932,7 @@ static TYPELIB my_locale_typelib_day_names_sl_SI = { array_elements(my_locale_day_names_sl_SI)-1, "", my_locale_day_names_sl_SI, NULL }; static TYPELIB my_locale_typelib_ab_day_names_sl_SI = { array_elements(my_locale_ab_day_names_sl_SI)-1, "", my_locale_ab_day_names_sl_SI, NULL }; -MY_LOCALE my_locale_sl_SI= - { "sl_SI", "Slovenian - Slovenia", FALSE, &my_locale_typelib_month_names_sl_SI, &my_locale_typelib_ab_month_names_sl_SI, &my_locale_typelib_day_names_sl_SI, &my_locale_typelib_ab_day_names_sl_SI }; +MY_LOCALE my_locale_sl_SI ( "sl_SI", "Slovenian - Slovenia", FALSE, &my_locale_typelib_month_names_sl_SI, &my_locale_typelib_ab_month_names_sl_SI, &my_locale_typelib_day_names_sl_SI, &my_locale_typelib_ab_day_names_sl_SI ); /***** LOCALE END sl_SI *****/ /***** LOCALE BEGIN sq_AL: Albanian - Albania *****/ @@ -997,8 +952,7 @@ static TYPELIB my_locale_typelib_day_names_sq_AL = { array_elements(my_locale_day_names_sq_AL)-1, "", my_locale_day_names_sq_AL, NULL }; static TYPELIB my_locale_typelib_ab_day_names_sq_AL = { array_elements(my_locale_ab_day_names_sq_AL)-1, "", my_locale_ab_day_names_sq_AL, NULL }; -MY_LOCALE my_locale_sq_AL= - { "sq_AL", "Albanian - Albania", FALSE, &my_locale_typelib_month_names_sq_AL, &my_locale_typelib_ab_month_names_sq_AL, &my_locale_typelib_day_names_sq_AL, &my_locale_typelib_ab_day_names_sq_AL }; +MY_LOCALE my_locale_sq_AL ( "sq_AL", "Albanian - Albania", FALSE, &my_locale_typelib_month_names_sq_AL, &my_locale_typelib_ab_month_names_sq_AL, &my_locale_typelib_day_names_sq_AL, &my_locale_typelib_ab_day_names_sq_AL ); /***** LOCALE END sq_AL *****/ /***** LOCALE BEGIN sr_YU: Servian - Yugoslavia *****/ @@ -1018,8 +972,7 @@ static TYPELIB my_locale_typelib_day_names_sr_YU = { array_elements(my_locale_day_names_sr_YU)-1, "", my_locale_day_names_sr_YU, NULL }; static TYPELIB my_locale_typelib_ab_day_names_sr_YU = { array_elements(my_locale_ab_day_names_sr_YU)-1, "", my_locale_ab_day_names_sr_YU, NULL }; -MY_LOCALE my_locale_sr_YU= - { "sr_YU", "Servian - Yugoslavia", FALSE, &my_locale_typelib_month_names_sr_YU, &my_locale_typelib_ab_month_names_sr_YU, &my_locale_typelib_day_names_sr_YU, &my_locale_typelib_ab_day_names_sr_YU }; +MY_LOCALE my_locale_sr_YU ( "sr_YU", "Servian - Yugoslavia", FALSE, &my_locale_typelib_month_names_sr_YU, &my_locale_typelib_ab_month_names_sr_YU, &my_locale_typelib_day_names_sr_YU, &my_locale_typelib_ab_day_names_sr_YU ); /***** LOCALE END sr_YU *****/ /***** LOCALE BEGIN sv_SE: Swedish - Sweden *****/ @@ -1039,8 +992,7 @@ static TYPELIB my_locale_typelib_day_names_sv_SE = { array_elements(my_locale_day_names_sv_SE)-1, "", my_locale_day_names_sv_SE, NULL }; static TYPELIB my_locale_typelib_ab_day_names_sv_SE = { array_elements(my_locale_ab_day_names_sv_SE)-1, "", my_locale_ab_day_names_sv_SE, NULL }; -MY_LOCALE my_locale_sv_SE= - { "sv_SE", "Swedish - Sweden", FALSE, &my_locale_typelib_month_names_sv_SE, &my_locale_typelib_ab_month_names_sv_SE, &my_locale_typelib_day_names_sv_SE, &my_locale_typelib_ab_day_names_sv_SE }; +MY_LOCALE my_locale_sv_SE ( "sv_SE", "Swedish - Sweden", FALSE, &my_locale_typelib_month_names_sv_SE, &my_locale_typelib_ab_month_names_sv_SE, &my_locale_typelib_day_names_sv_SE, &my_locale_typelib_ab_day_names_sv_SE ); /***** LOCALE END sv_SE *****/ /***** LOCALE BEGIN ta_IN: Tamil - India *****/ @@ -1060,8 +1012,7 @@ static TYPELIB my_locale_typelib_day_names_ta_IN = { array_elements(my_locale_day_names_ta_IN)-1, "", my_locale_day_names_ta_IN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ta_IN = { array_elements(my_locale_ab_day_names_ta_IN)-1, "", my_locale_ab_day_names_ta_IN, NULL }; -MY_LOCALE my_locale_ta_IN= - { "ta_IN", "Tamil - India", FALSE, &my_locale_typelib_month_names_ta_IN, &my_locale_typelib_ab_month_names_ta_IN, &my_locale_typelib_day_names_ta_IN, &my_locale_typelib_ab_day_names_ta_IN }; +MY_LOCALE my_locale_ta_IN ( "ta_IN", "Tamil - India", FALSE, &my_locale_typelib_month_names_ta_IN, &my_locale_typelib_ab_month_names_ta_IN, &my_locale_typelib_day_names_ta_IN, &my_locale_typelib_ab_day_names_ta_IN ); /***** LOCALE END ta_IN *****/ /***** LOCALE BEGIN te_IN: Telugu - India *****/ @@ -1081,8 +1032,7 @@ static TYPELIB my_locale_typelib_day_names_te_IN = { array_elements(my_locale_day_names_te_IN)-1, "", my_locale_day_names_te_IN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_te_IN = { array_elements(my_locale_ab_day_names_te_IN)-1, "", my_locale_ab_day_names_te_IN, NULL }; -MY_LOCALE my_locale_te_IN= - { "te_IN", "Telugu - India", FALSE, &my_locale_typelib_month_names_te_IN, &my_locale_typelib_ab_month_names_te_IN, &my_locale_typelib_day_names_te_IN, &my_locale_typelib_ab_day_names_te_IN }; +MY_LOCALE my_locale_te_IN ( "te_IN", "Telugu - India", FALSE, &my_locale_typelib_month_names_te_IN, &my_locale_typelib_ab_month_names_te_IN, &my_locale_typelib_day_names_te_IN, &my_locale_typelib_ab_day_names_te_IN ); /***** LOCALE END te_IN *****/ /***** LOCALE BEGIN th_TH: Thai - Thailand *****/ @@ -1102,8 +1052,7 @@ static TYPELIB my_locale_typelib_day_names_th_TH = { array_elements(my_locale_day_names_th_TH)-1, "", my_locale_day_names_th_TH, NULL }; static TYPELIB my_locale_typelib_ab_day_names_th_TH = { array_elements(my_locale_ab_day_names_th_TH)-1, "", my_locale_ab_day_names_th_TH, NULL }; -MY_LOCALE my_locale_th_TH= - { "th_TH", "Thai - Thailand", FALSE, &my_locale_typelib_month_names_th_TH, &my_locale_typelib_ab_month_names_th_TH, &my_locale_typelib_day_names_th_TH, &my_locale_typelib_ab_day_names_th_TH }; +MY_LOCALE my_locale_th_TH ( "th_TH", "Thai - Thailand", FALSE, &my_locale_typelib_month_names_th_TH, &my_locale_typelib_ab_month_names_th_TH, &my_locale_typelib_day_names_th_TH, &my_locale_typelib_ab_day_names_th_TH ); /***** LOCALE END th_TH *****/ /***** LOCALE BEGIN tr_TR: Turkish - Turkey *****/ @@ -1123,8 +1072,7 @@ static TYPELIB my_locale_typelib_day_names_tr_TR = { array_elements(my_locale_day_names_tr_TR)-1, "", my_locale_day_names_tr_TR, NULL }; static TYPELIB my_locale_typelib_ab_day_names_tr_TR = { array_elements(my_locale_ab_day_names_tr_TR)-1, "", my_locale_ab_day_names_tr_TR, NULL }; -MY_LOCALE my_locale_tr_TR= - { "tr_TR", "Turkish - Turkey", FALSE, &my_locale_typelib_month_names_tr_TR, &my_locale_typelib_ab_month_names_tr_TR, &my_locale_typelib_day_names_tr_TR, &my_locale_typelib_ab_day_names_tr_TR }; +MY_LOCALE my_locale_tr_TR ( "tr_TR", "Turkish - Turkey", FALSE, &my_locale_typelib_month_names_tr_TR, &my_locale_typelib_ab_month_names_tr_TR, &my_locale_typelib_day_names_tr_TR, &my_locale_typelib_ab_day_names_tr_TR ); /***** LOCALE END tr_TR *****/ /***** LOCALE BEGIN uk_UA: Ukrainian - Ukraine *****/ @@ -1144,8 +1092,7 @@ static TYPELIB my_locale_typelib_day_names_uk_UA = { array_elements(my_locale_day_names_uk_UA)-1, "", my_locale_day_names_uk_UA, NULL }; static TYPELIB my_locale_typelib_ab_day_names_uk_UA = { array_elements(my_locale_ab_day_names_uk_UA)-1, "", my_locale_ab_day_names_uk_UA, NULL }; -MY_LOCALE my_locale_uk_UA= - { "uk_UA", "Ukrainian - Ukraine", FALSE, &my_locale_typelib_month_names_uk_UA, &my_locale_typelib_ab_month_names_uk_UA, &my_locale_typelib_day_names_uk_UA, &my_locale_typelib_ab_day_names_uk_UA }; +MY_LOCALE my_locale_uk_UA ( "uk_UA", "Ukrainian - Ukraine", FALSE, &my_locale_typelib_month_names_uk_UA, &my_locale_typelib_ab_month_names_uk_UA, &my_locale_typelib_day_names_uk_UA, &my_locale_typelib_ab_day_names_uk_UA ); /***** LOCALE END uk_UA *****/ /***** LOCALE BEGIN ur_PK: Urdu - Pakistan *****/ @@ -1165,8 +1112,7 @@ static TYPELIB my_locale_typelib_day_names_ur_PK = { array_elements(my_locale_day_names_ur_PK)-1, "", my_locale_day_names_ur_PK, NULL }; static TYPELIB my_locale_typelib_ab_day_names_ur_PK = { array_elements(my_locale_ab_day_names_ur_PK)-1, "", my_locale_ab_day_names_ur_PK, NULL }; -MY_LOCALE my_locale_ur_PK= - { "ur_PK", "Urdu - Pakistan", FALSE, &my_locale_typelib_month_names_ur_PK, &my_locale_typelib_ab_month_names_ur_PK, &my_locale_typelib_day_names_ur_PK, &my_locale_typelib_ab_day_names_ur_PK }; +MY_LOCALE my_locale_ur_PK ( "ur_PK", "Urdu - Pakistan", FALSE, &my_locale_typelib_month_names_ur_PK, &my_locale_typelib_ab_month_names_ur_PK, &my_locale_typelib_day_names_ur_PK, &my_locale_typelib_ab_day_names_ur_PK ); /***** LOCALE END ur_PK *****/ /***** LOCALE BEGIN vi_VN: Vietnamese - Vietnam *****/ @@ -1186,8 +1132,7 @@ static TYPELIB my_locale_typelib_day_names_vi_VN = { array_elements(my_locale_day_names_vi_VN)-1, "", my_locale_day_names_vi_VN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_vi_VN = { array_elements(my_locale_ab_day_names_vi_VN)-1, "", my_locale_ab_day_names_vi_VN, NULL }; -MY_LOCALE my_locale_vi_VN= - { "vi_VN", "Vietnamese - Vietnam", FALSE, &my_locale_typelib_month_names_vi_VN, &my_locale_typelib_ab_month_names_vi_VN, &my_locale_typelib_day_names_vi_VN, &my_locale_typelib_ab_day_names_vi_VN }; +MY_LOCALE my_locale_vi_VN ( "vi_VN", "Vietnamese - Vietnam", FALSE, &my_locale_typelib_month_names_vi_VN, &my_locale_typelib_ab_month_names_vi_VN, &my_locale_typelib_day_names_vi_VN, &my_locale_typelib_ab_day_names_vi_VN ); /***** LOCALE END vi_VN *****/ /***** LOCALE BEGIN zh_CN: Chinese - Peoples Republic of China *****/ @@ -1207,8 +1152,7 @@ static TYPELIB my_locale_typelib_day_names_zh_CN = { array_elements(my_locale_day_names_zh_CN)-1, "", my_locale_day_names_zh_CN, NULL }; static TYPELIB my_locale_typelib_ab_day_names_zh_CN = { array_elements(my_locale_ab_day_names_zh_CN)-1, "", my_locale_ab_day_names_zh_CN, NULL }; -MY_LOCALE my_locale_zh_CN= - { "zh_CN", "Chinese - Peoples Republic of China", FALSE, &my_locale_typelib_month_names_zh_CN, &my_locale_typelib_ab_month_names_zh_CN, &my_locale_typelib_day_names_zh_CN, &my_locale_typelib_ab_day_names_zh_CN }; +MY_LOCALE my_locale_zh_CN ( "zh_CN", "Chinese - Peoples Republic of China", FALSE, &my_locale_typelib_month_names_zh_CN, &my_locale_typelib_ab_month_names_zh_CN, &my_locale_typelib_day_names_zh_CN, &my_locale_typelib_ab_day_names_zh_CN ); /***** LOCALE END zh_CN *****/ /***** LOCALE BEGIN zh_TW: Chinese - Taiwan *****/ @@ -1228,268 +1172,215 @@ static TYPELIB my_locale_typelib_day_names_zh_TW = { array_elements(my_locale_day_names_zh_TW)-1, "", my_locale_day_names_zh_TW, NULL }; static TYPELIB my_locale_typelib_ab_day_names_zh_TW = { array_elements(my_locale_ab_day_names_zh_TW)-1, "", my_locale_ab_day_names_zh_TW, NULL }; -MY_LOCALE my_locale_zh_TW= - { "zh_TW", "Chinese - Taiwan", FALSE, &my_locale_typelib_month_names_zh_TW, &my_locale_typelib_ab_month_names_zh_TW, &my_locale_typelib_day_names_zh_TW, &my_locale_typelib_ab_day_names_zh_TW }; +MY_LOCALE my_locale_zh_TW ( "zh_TW", "Chinese - Taiwan", FALSE, &my_locale_typelib_month_names_zh_TW, &my_locale_typelib_ab_month_names_zh_TW, &my_locale_typelib_day_names_zh_TW, &my_locale_typelib_ab_day_names_zh_TW ); /***** LOCALE END zh_TW *****/ /***** LOCALE BEGIN ar_DZ: Arabic - Algeria *****/ -MY_LOCALE my_locale_ar_DZ= - { "ar_DZ", "Arabic - Algeria", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_DZ ( "ar_DZ", "Arabic - Algeria", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_DZ *****/ /***** LOCALE BEGIN ar_EG: Arabic - Egypt *****/ -MY_LOCALE my_locale_ar_EG= - { "ar_EG", "Arabic - Egypt", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_EG ( "ar_EG", "Arabic - Egypt", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_EG *****/ /***** LOCALE BEGIN ar_IN: Arabic - Iran *****/ -MY_LOCALE my_locale_ar_IN= - { "ar_IN", "Arabic - Iran", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_IN ( "ar_IN", "Arabic - Iran", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_IN *****/ /***** LOCALE BEGIN ar_IQ: Arabic - Iraq *****/ -MY_LOCALE my_locale_ar_IQ= - { "ar_IQ", "Arabic - Iraq", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_IQ ( "ar_IQ", "Arabic - Iraq", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_IQ *****/ /***** LOCALE BEGIN ar_KW: Arabic - Kuwait *****/ -MY_LOCALE my_locale_ar_KW= - { "ar_KW", "Arabic - Kuwait", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_KW ( "ar_KW", "Arabic - Kuwait", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_KW *****/ /***** LOCALE BEGIN ar_LB: Arabic - Lebanon *****/ -MY_LOCALE my_locale_ar_LB= - { "ar_LB", "Arabic - Lebanon", FALSE, &my_locale_typelib_month_names_ar_JO, &my_locale_typelib_ab_month_names_ar_JO, &my_locale_typelib_day_names_ar_JO, &my_locale_typelib_ab_day_names_ar_JO }; +MY_LOCALE my_locale_ar_LB ( "ar_LB", "Arabic - Lebanon", FALSE, &my_locale_typelib_month_names_ar_JO, &my_locale_typelib_ab_month_names_ar_JO, &my_locale_typelib_day_names_ar_JO, &my_locale_typelib_ab_day_names_ar_JO ); /***** LOCALE END ar_LB *****/ /***** LOCALE BEGIN ar_LY: Arabic - Libya *****/ -MY_LOCALE my_locale_ar_LY= - { "ar_LY", "Arabic - Libya", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_LY ( "ar_LY", "Arabic - Libya", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_LY *****/ /***** LOCALE BEGIN ar_MA: Arabic - Morocco *****/ -MY_LOCALE my_locale_ar_MA= - { "ar_MA", "Arabic - Morocco", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_MA ( "ar_MA", "Arabic - Morocco", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_MA *****/ /***** LOCALE BEGIN ar_OM: Arabic - Oman *****/ -MY_LOCALE my_locale_ar_OM= - { "ar_OM", "Arabic - Oman", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_OM ( "ar_OM", "Arabic - Oman", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_OM *****/ /***** LOCALE BEGIN ar_QA: Arabic - Qatar *****/ -MY_LOCALE my_locale_ar_QA= - { "ar_QA", "Arabic - Qatar", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_QA ( "ar_QA", "Arabic - Qatar", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_QA *****/ /***** LOCALE BEGIN ar_SD: Arabic - Sudan *****/ -MY_LOCALE my_locale_ar_SD= - { "ar_SD", "Arabic - Sudan", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_SD ( "ar_SD", "Arabic - Sudan", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_SD *****/ /***** LOCALE BEGIN ar_TN: Arabic - Tunisia *****/ -MY_LOCALE my_locale_ar_TN= - { "ar_TN", "Arabic - Tunisia", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_TN ( "ar_TN", "Arabic - Tunisia", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_TN *****/ /***** LOCALE BEGIN ar_YE: Arabic - Yemen *****/ -MY_LOCALE my_locale_ar_YE= - { "ar_YE", "Arabic - Yemen", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH }; +MY_LOCALE my_locale_ar_YE ( "ar_YE", "Arabic - Yemen", FALSE, &my_locale_typelib_month_names_ar_BH, &my_locale_typelib_ab_month_names_ar_BH, &my_locale_typelib_day_names_ar_BH, &my_locale_typelib_ab_day_names_ar_BH ); /***** LOCALE END ar_YE *****/ /***** LOCALE BEGIN de_BE: German - Belgium *****/ -MY_LOCALE my_locale_de_BE= - { "de_BE", "German - Belgium", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE }; +MY_LOCALE my_locale_de_BE ( "de_BE", "German - Belgium", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE ); /***** LOCALE END de_BE *****/ /***** LOCALE BEGIN de_CH: German - Switzerland *****/ -MY_LOCALE my_locale_de_CH= - { "de_CH", "German - Switzerland", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE }; +MY_LOCALE my_locale_de_CH ( "de_CH", "German - Switzerland", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE ); /***** LOCALE END de_CH *****/ /***** LOCALE BEGIN de_LU: German - Luxembourg *****/ -MY_LOCALE my_locale_de_LU= - { "de_LU", "German - Luxembourg", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE }; +MY_LOCALE my_locale_de_LU ( "de_LU", "German - Luxembourg", FALSE, &my_locale_typelib_month_names_de_DE, &my_locale_typelib_ab_month_names_de_DE, &my_locale_typelib_day_names_de_DE, &my_locale_typelib_ab_day_names_de_DE ); /***** LOCALE END de_LU *****/ /***** LOCALE BEGIN en_AU: English - Australia *****/ -MY_LOCALE my_locale_en_AU= - { "en_AU", "English - Australia", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_AU ( "en_AU", "English - Australia", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_AU *****/ /***** LOCALE BEGIN en_CA: English - Canada *****/ -MY_LOCALE my_locale_en_CA= - { "en_CA", "English - Canada", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_CA ( "en_CA", "English - Canada", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_CA *****/ /***** LOCALE BEGIN en_GB: English - United Kingdom *****/ -MY_LOCALE my_locale_en_GB= - { "en_GB", "English - United Kingdom", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_GB ( "en_GB", "English - United Kingdom", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_GB *****/ /***** LOCALE BEGIN en_IN: English - India *****/ -MY_LOCALE my_locale_en_IN= - { "en_IN", "English - India", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_IN ( "en_IN", "English - India", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_IN *****/ /***** LOCALE BEGIN en_NZ: English - New Zealand *****/ -MY_LOCALE my_locale_en_NZ= - { "en_NZ", "English - New Zealand", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_NZ ( "en_NZ", "English - New Zealand", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_NZ *****/ /***** LOCALE BEGIN en_PH: English - Philippines *****/ -MY_LOCALE my_locale_en_PH= - { "en_PH", "English - Philippines", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_PH ( "en_PH", "English - Philippines", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_PH *****/ /***** LOCALE BEGIN en_ZA: English - South Africa *****/ -MY_LOCALE my_locale_en_ZA= - { "en_ZA", "English - South Africa", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_ZA ( "en_ZA", "English - South Africa", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_ZA *****/ /***** LOCALE BEGIN en_ZW: English - Zimbabwe *****/ -MY_LOCALE my_locale_en_ZW= - { "en_ZW", "English - Zimbabwe", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US }; +MY_LOCALE my_locale_en_ZW ( "en_ZW", "English - Zimbabwe", TRUE, &my_locale_typelib_month_names_en_US, &my_locale_typelib_ab_month_names_en_US, &my_locale_typelib_day_names_en_US, &my_locale_typelib_ab_day_names_en_US ); /***** LOCALE END en_ZW *****/ /***** LOCALE BEGIN es_AR: Spanish - Argentina *****/ -MY_LOCALE my_locale_es_AR= - { "es_AR", "Spanish - Argentina", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_AR ( "es_AR", "Spanish - Argentina", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_AR *****/ /***** LOCALE BEGIN es_BO: Spanish - Bolivia *****/ -MY_LOCALE my_locale_es_BO= - { "es_BO", "Spanish - Bolivia", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_BO ( "es_BO", "Spanish - Bolivia", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_BO *****/ /***** LOCALE BEGIN es_CL: Spanish - Chile *****/ -MY_LOCALE my_locale_es_CL= - { "es_CL", "Spanish - Chile", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_CL ( "es_CL", "Spanish - Chile", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_CL *****/ /***** LOCALE BEGIN es_CO: Spanish - Columbia *****/ -MY_LOCALE my_locale_es_CO= - { "es_CO", "Spanish - Columbia", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_CO ( "es_CO", "Spanish - Columbia", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_CO *****/ /***** LOCALE BEGIN es_CR: Spanish - Costa Rica *****/ -MY_LOCALE my_locale_es_CR= - { "es_CR", "Spanish - Costa Rica", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_CR ( "es_CR", "Spanish - Costa Rica", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_CR *****/ /***** LOCALE BEGIN es_DO: Spanish - Dominican Republic *****/ -MY_LOCALE my_locale_es_DO= - { "es_DO", "Spanish - Dominican Republic", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_DO ( "es_DO", "Spanish - Dominican Republic", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_DO *****/ /***** LOCALE BEGIN es_EC: Spanish - Ecuador *****/ -MY_LOCALE my_locale_es_EC= - { "es_EC", "Spanish - Ecuador", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_EC ( "es_EC", "Spanish - Ecuador", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_EC *****/ /***** LOCALE BEGIN es_GT: Spanish - Guatemala *****/ -MY_LOCALE my_locale_es_GT= - { "es_GT", "Spanish - Guatemala", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_GT ( "es_GT", "Spanish - Guatemala", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_GT *****/ /***** LOCALE BEGIN es_HN: Spanish - Honduras *****/ -MY_LOCALE my_locale_es_HN= - { "es_HN", "Spanish - Honduras", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_HN ( "es_HN", "Spanish - Honduras", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_HN *****/ /***** LOCALE BEGIN es_MX: Spanish - Mexico *****/ -MY_LOCALE my_locale_es_MX= - { "es_MX", "Spanish - Mexico", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_MX ( "es_MX", "Spanish - Mexico", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_MX *****/ /***** LOCALE BEGIN es_NI: Spanish - Nicaragua *****/ -MY_LOCALE my_locale_es_NI= - { "es_NI", "Spanish - Nicaragua", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_NI ( "es_NI", "Spanish - Nicaragua", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_NI *****/ /***** LOCALE BEGIN es_PA: Spanish - Panama *****/ -MY_LOCALE my_locale_es_PA= - { "es_PA", "Spanish - Panama", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_PA ( "es_PA", "Spanish - Panama", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_PA *****/ /***** LOCALE BEGIN es_PE: Spanish - Peru *****/ -MY_LOCALE my_locale_es_PE= - { "es_PE", "Spanish - Peru", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_PE ( "es_PE", "Spanish - Peru", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_PE *****/ /***** LOCALE BEGIN es_PR: Spanish - Puerto Rico *****/ -MY_LOCALE my_locale_es_PR= - { "es_PR", "Spanish - Puerto Rico", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_PR ( "es_PR", "Spanish - Puerto Rico", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_PR *****/ /***** LOCALE BEGIN es_PY: Spanish - Paraguay *****/ -MY_LOCALE my_locale_es_PY= - { "es_PY", "Spanish - Paraguay", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_PY ( "es_PY", "Spanish - Paraguay", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_PY *****/ /***** LOCALE BEGIN es_SV: Spanish - El Salvador *****/ -MY_LOCALE my_locale_es_SV= - { "es_SV", "Spanish - El Salvador", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_SV ( "es_SV", "Spanish - El Salvador", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_SV *****/ /***** LOCALE BEGIN es_US: Spanish - United States *****/ -MY_LOCALE my_locale_es_US= - { "es_US", "Spanish - United States", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_US ( "es_US", "Spanish - United States", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_US *****/ /***** LOCALE BEGIN es_UY: Spanish - Uruguay *****/ -MY_LOCALE my_locale_es_UY= - { "es_UY", "Spanish - Uruguay", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_UY ( "es_UY", "Spanish - Uruguay", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_UY *****/ /***** LOCALE BEGIN es_VE: Spanish - Venezuela *****/ -MY_LOCALE my_locale_es_VE= - { "es_VE", "Spanish - Venezuela", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES }; +MY_LOCALE my_locale_es_VE ( "es_VE", "Spanish - Venezuela", FALSE, &my_locale_typelib_month_names_es_ES, &my_locale_typelib_ab_month_names_es_ES, &my_locale_typelib_day_names_es_ES, &my_locale_typelib_ab_day_names_es_ES ); /***** LOCALE END es_VE *****/ /***** LOCALE BEGIN fr_BE: French - Belgium *****/ -MY_LOCALE my_locale_fr_BE= - { "fr_BE", "French - Belgium", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR }; +MY_LOCALE my_locale_fr_BE ( "fr_BE", "French - Belgium", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR ); /***** LOCALE END fr_BE *****/ /***** LOCALE BEGIN fr_CA: French - Canada *****/ -MY_LOCALE my_locale_fr_CA= - { "fr_CA", "French - Canada", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR }; +MY_LOCALE my_locale_fr_CA ( "fr_CA", "French - Canada", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR ); /***** LOCALE END fr_CA *****/ /***** LOCALE BEGIN fr_CH: French - Switzerland *****/ -MY_LOCALE my_locale_fr_CH= - { "fr_CH", "French - Switzerland", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR }; +MY_LOCALE my_locale_fr_CH ( "fr_CH", "French - Switzerland", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR ); /***** LOCALE END fr_CH *****/ /***** LOCALE BEGIN fr_LU: French - Luxembourg *****/ -MY_LOCALE my_locale_fr_LU= - { "fr_LU", "French - Luxembourg", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR }; +MY_LOCALE my_locale_fr_LU ( "fr_LU", "French - Luxembourg", FALSE, &my_locale_typelib_month_names_fr_FR, &my_locale_typelib_ab_month_names_fr_FR, &my_locale_typelib_day_names_fr_FR, &my_locale_typelib_ab_day_names_fr_FR ); /***** LOCALE END fr_LU *****/ /***** LOCALE BEGIN it_IT: Italian - Italy *****/ -MY_LOCALE my_locale_it_IT= - { "it_IT", "Italian - Italy", FALSE, &my_locale_typelib_month_names_it_CH, &my_locale_typelib_ab_month_names_it_CH, &my_locale_typelib_day_names_it_CH, &my_locale_typelib_ab_day_names_it_CH }; +MY_LOCALE my_locale_it_IT ( "it_IT", "Italian - Italy", FALSE, &my_locale_typelib_month_names_it_CH, &my_locale_typelib_ab_month_names_it_CH, &my_locale_typelib_day_names_it_CH, &my_locale_typelib_ab_day_names_it_CH ); /***** LOCALE END it_IT *****/ /***** LOCALE BEGIN nl_BE: Dutch - Belgium *****/ -MY_LOCALE my_locale_nl_BE= - { "nl_BE", "Dutch - Belgium", TRUE, &my_locale_typelib_month_names_nl_NL, &my_locale_typelib_ab_month_names_nl_NL, &my_locale_typelib_day_names_nl_NL, &my_locale_typelib_ab_day_names_nl_NL }; +MY_LOCALE my_locale_nl_BE ( "nl_BE", "Dutch - Belgium", TRUE, &my_locale_typelib_month_names_nl_NL, &my_locale_typelib_ab_month_names_nl_NL, &my_locale_typelib_day_names_nl_NL, &my_locale_typelib_ab_day_names_nl_NL ); /***** LOCALE END nl_BE *****/ /***** LOCALE BEGIN no_NO: Norwegian - Norway *****/ -MY_LOCALE my_locale_no_NO= - { "no_NO", "Norwegian - Norway", FALSE, &my_locale_typelib_month_names_nb_NO, &my_locale_typelib_ab_month_names_nb_NO, &my_locale_typelib_day_names_nb_NO, &my_locale_typelib_ab_day_names_nb_NO }; +MY_LOCALE my_locale_no_NO ( "no_NO", "Norwegian - Norway", FALSE, &my_locale_typelib_month_names_nb_NO, &my_locale_typelib_ab_month_names_nb_NO, &my_locale_typelib_day_names_nb_NO, &my_locale_typelib_ab_day_names_nb_NO ); /***** LOCALE END no_NO *****/ /***** LOCALE BEGIN sv_FI: Swedish - Finland *****/ -MY_LOCALE my_locale_sv_FI= - { "sv_FI", "Swedish - Finland", FALSE, &my_locale_typelib_month_names_sv_SE, &my_locale_typelib_ab_month_names_sv_SE, &my_locale_typelib_day_names_sv_SE, &my_locale_typelib_ab_day_names_sv_SE }; +MY_LOCALE my_locale_sv_FI ( "sv_FI", "Swedish - Finland", FALSE, &my_locale_typelib_month_names_sv_SE, &my_locale_typelib_ab_month_names_sv_SE, &my_locale_typelib_day_names_sv_SE, &my_locale_typelib_ab_day_names_sv_SE ); /***** LOCALE END sv_FI *****/ /***** LOCALE BEGIN zh_HK: Chinese - Hong Kong SAR *****/ -MY_LOCALE my_locale_zh_HK= - { "zh_HK", "Chinese - Hong Kong SAR", FALSE, &my_locale_typelib_month_names_zh_CN, &my_locale_typelib_ab_month_names_zh_CN, &my_locale_typelib_day_names_zh_CN, &my_locale_typelib_ab_day_names_zh_CN }; +MY_LOCALE my_locale_zh_HK ( "zh_HK", "Chinese - Hong Kong SAR", FALSE, &my_locale_typelib_month_names_zh_CN, &my_locale_typelib_ab_month_names_zh_CN, &my_locale_typelib_day_names_zh_CN, &my_locale_typelib_ab_day_names_zh_CN ); /***** LOCALE END zh_HK *****/ MY_LOCALE *my_locales[]= diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 28ed3e25d57..d809c1b2cb0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1001,8 +1001,8 @@ static int check_connection(THD *thd) char *passwd= strend(user)+1; uint user_len= passwd - user - 1; char *db= passwd; - char db_buff[NAME_LEN+1]; // buffer to store db in utf8 - char user_buff[USERNAME_LENGTH+1]; // buffer to store user in utf8 + char db_buff[NAME_BYTE_LEN + 1]; // buffer to store db in utf8 + char user_buff[USERNAME_BYTE_LENGTH + 1]; // buffer to store user in utf8 uint dummy_errors; /* @@ -1662,7 +1662,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, password. New clients send the size (1 byte) + string (not null terminated, so also '\0' for empty string). */ - char db_buff[NAME_LEN+1]; // buffer to store db in utf8 + char db_buff[NAME_BYTE_LEN+1]; // buffer to store db in utf8 char *db= passwd; uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ? *passwd++ : strlen(passwd); @@ -3344,8 +3344,6 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if ((res= insert_precheck(thd, all_tables))) break; - /* Skip first table, which is the table we are inserting in */ - select_lex->context.table_list= first_table->next_local; if (!thd->locked_tables && !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) @@ -4413,9 +4411,6 @@ end_with_restore_list: } else { -#ifndef NO_EMBEDDED_ACCESS_CHECKS - Security_context *save_ctx; -#endif ha_rows select_limit; /* bits that should be cleared in thd->server_status */ uint bits_to_be_cleared= 0; @@ -4457,21 +4452,11 @@ end_with_restore_list: #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_routine_access(thd, EXECUTE_ACL, - sp->m_db.str, sp->m_name.str, TRUE, 0) || - sp_change_security_context(thd, sp, &save_ctx)) - { - thd->net.no_send_ok= nsok; - goto error; - } - if (save_ctx && - check_routine_access(thd, EXECUTE_ACL, - sp->m_db.str, sp->m_name.str, TRUE, 0)) + sp->m_db.str, sp->m_name.str, TRUE, FALSE)) { thd->net.no_send_ok= nsok; - sp_restore_security_context(thd, save_ctx); goto error; } - #endif select_limit= thd->variables.select_limit; thd->variables.select_limit= HA_POS_ERROR; @@ -4495,9 +4480,6 @@ end_with_restore_list: thd->total_warn_count= 0; thd->variables.select_limit= select_limit; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - sp_restore_security_context(thd, save_ctx); -#endif thd->net.no_send_ok= nsok; thd->server_status&= ~bits_to_be_cleared; @@ -5115,10 +5097,21 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables) return 1; /* Check rights on tables of subselects and implictly opened tables */ - TABLE_LIST *subselects_tables; + TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0; if ((subselects_tables= all_tables->next_global)) { - if ((check_table_access(thd, SELECT_ACL, subselects_tables, 0))) + /* + Access rights asked for the first table of a view should be the same + as for the view + */ + if (view && subselects_tables->belong_to_view == view) + { + if (check_single_table_access (thd, privilege, subselects_tables)) + return 1; + subselects_tables= subselects_tables->next_global; + } + if (subselects_tables && + (check_table_access(thd, SELECT_ACL, subselects_tables, 0))) return 1; } return 0; @@ -5792,7 +5785,6 @@ void mysql_init_multi_delete(LEX *lex) lex->query_tables_last= &lex->query_tables; } - /* When you modify mysql_parse(), you may need to mofify mysql_test_parse_for_slave() in this same file. @@ -5801,6 +5793,9 @@ void mysql_init_multi_delete(LEX *lex) void mysql_parse(THD *thd, char *inBuf, uint length) { DBUG_ENTER("mysql_parse"); + + DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on();); + mysql_init_query(thd, (uchar*) inBuf, length); if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { @@ -6695,11 +6690,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, select_errors=0; /* Write if more errors */ bool tmp_write_to_binlog= 1; - if (thd && thd->in_sub_stmt) - { - my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH"); - return 1; - } + DBUG_ASSERT(!thd || !thd->in_sub_stmt); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (options & REFRESH_GRANT) @@ -7017,7 +7008,7 @@ Item * all_any_subquery_creator(Item *left_expr, return new Item_func_not(new Item_in_subselect(left_expr, select_lex)); Item_allany_subselect *it= - new Item_allany_subselect(left_expr, (*cmp)(all), select_lex, all); + new Item_allany_subselect(left_expr, cmp, select_lex, all); if (all) return it->upper_item= new Item_func_not_all(it); /* ALL */ @@ -7547,16 +7538,35 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name) LEX_USER *get_current_user(THD *thd, LEX_USER *user) { - LEX_USER *curr_user; if (!user->user.str) // current_user - { - if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(LEX_USER)))) - { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(LEX_USER)); - return 0; - } - get_default_definer(thd, curr_user); - return curr_user; - } + return create_default_definer(thd); + return user; } + + +/* + Check that length of a string does not exceed some limit. + + SYNOPSIS + check_string_length() + cs string charset + str string to be checked + err_msg error message to be displayed if the string is too long + max_length max length + + RETURN + FALSE the passed string is not longer than max_length + TRUE the passed string is longer than max_length +*/ + +bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str, + const char *err_msg, uint max_length) +{ + if (cs->cset->charpos(cs, str->str, str->str + str->length, + max_length) >= str->length) + return FALSE; + + my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length); + return TRUE; +} diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ffe54310843..32f0ca6859d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1877,7 +1877,8 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length) thd->stmt_map.erase(stmt); } else - mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %s", stmt->id, packet); + mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %.*b", stmt->id, + stmt->query_length, stmt->query); /* check_prepared_statemnt sends the metadata packet in case of success */ DBUG_VOID_RETURN; @@ -2128,29 +2129,21 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) they have their own table list). */ for (TABLE_LIST *tables= lex->query_tables; - tables; - tables= tables->next_global) + tables; + tables= tables->next_global) + { + tables->reinit_before_use(thd); + } + /* + Cleanup of the special case of DELETE t1, t2 FROM t1, t2, t3 ... + (multi-delete). We do a full clean up, although at the moment all we + need to clean in the tables of MULTI-DELETE list is 'table' member. + */ + for (TABLE_LIST *tables= (TABLE_LIST*) lex->auxiliary_table_list.first; + tables; + tables= tables->next_global) { - /* - Reset old pointers to TABLEs: they are not valid since the tables - were closed in the end of previous prepare or execute call. - */ tables->reinit_before_use(thd); - - /* Reset is_schema_table_processed value(needed for I_S tables */ - tables->is_schema_table_processed= FALSE; - - TABLE_LIST *embedded; /* The table at the current level of nesting. */ - TABLE_LIST *embedding= tables; /* The parent nested table reference. */ - do - { - embedded= embedding; - if (embedded->prep_on_expr) - embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd); - embedding= embedded->embedding; - } - while (embedding && - embedding->nested_join->join_list.head() == embedded); } lex->current_select= &lex->select_lex; @@ -2165,7 +2158,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) } lex->allow_sum_func= 0; lex->in_sum_func= NULL; - DBUG_VOID_RETURN; + DBUG_VOID_RETURN; } @@ -2260,7 +2253,8 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); if (error == 0) - mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query); + mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %.*b", stmt->id, + thd->query_length, thd->query); DBUG_VOID_RETURN; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ccda69522c7..e1933d42f9e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1494,10 +1494,14 @@ bool show_binlogs(THD* thd) if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); + + pthread_mutex_lock(mysql_bin_log.get_log_lock()); mysql_bin_log.lock_index(); index_file=mysql_bin_log.get_index_file(); - - mysql_bin_log.get_current_log(&cur); + + mysql_bin_log.raw_get_current_log(&cur); // dont take mutex + pthread_mutex_unlock(mysql_bin_log.get_log_lock()); // lockdep, OK + cur_dir_len= dirname_length(cur.log_file_name); reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0); diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 9eb6456ee20..6b1e5e6b447 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -22,7 +22,7 @@ typedef struct st_slave_info uint32 server_id; uint32 rpl_recovery_rank, master_id; char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_LENGTH+1]; + char user[USERNAME_BYTE_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; uint16 port; THD* thd; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 20512563f37..e9d0e003f6d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -344,7 +344,7 @@ JOIN::prepare(Item ***rref_pointer_array, setup_tables_and_check_access(thd, &select_lex->context, join_list, tables_list, &conds, &select_lex->leaf_tables, FALSE, - SELECT_ACL)) || + SELECT_ACL, SELECT_ACL)) || setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) || select_lex->setup_ref_array(thd, og_num) || setup_fields(thd, (*rref_pointer_array), fields_list, 1, @@ -679,6 +679,25 @@ JOIN::optimize() DBUG_PRINT("info",("Select tables optimized away")); zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved + /* + Extract all table-independent conditions and replace the WHERE + clause with them. All other conditions were computed by opt_sum_query + and the MIN/MAX/COUNT function(s) have been replaced by constants, + so there is no need to compute the whole WHERE clause again. + Notice that make_cond_for_table() will always succeed to remove all + computed conditions, because opt_sum_query() is applicable only to + conjunctions. + Preserve conditions for EXPLAIN. + */ + if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED)) + { + COND *table_independent_conds= + make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0); + DBUG_EXECUTE("where", + print_where(table_independent_conds, + "where after opt_sum_query()");); + conds= table_independent_conds; + } } } if (!tables_list) @@ -793,6 +812,40 @@ JOIN::optimize() if (!order && org_order) skip_sort_order= 1; } + /* + Check if we can optimize away GROUP BY/DISTINCT. + We can do that if there are no aggregate functions and the + fields in DISTINCT clause (if present) and/or columns in GROUP BY + (if present) contain direct references to all key parts of + an unique index (in whatever order). + Note that the unique keys for DISTINCT and GROUP BY should not + be the same (as long as they are unique). + + The FROM clause must contain a single non-constant table. + */ + if (tables - const_tables == 1 && (group_list || select_distinct) && + !tmp_table_param.sum_func_count && + (!join_tab[const_tables].select || + !join_tab[const_tables].select->quick || + join_tab[const_tables].select->quick->get_type() != + QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) + { + if (group_list && + list_contains_unique_index(join_tab[const_tables].table, + find_field_in_order_list, + (void *) group_list)) + { + group_list= 0; + group= 0; + } + if (select_distinct && + list_contains_unique_index(join_tab[const_tables].table, + find_field_in_item_list, + (void *) &fields_list)) + { + select_distinct= 0; + } + } if (group_list || tmp_table_param.sum_func_count) { if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE) @@ -862,40 +915,6 @@ JOIN::optimize() if (old_group_list && !group_list) select_distinct= 0; } - /* - Check if we can optimize away GROUP BY/DISTINCT. - We can do that if there are no aggregate functions and the - fields in DISTINCT clause (if present) and/or columns in GROUP BY - (if present) contain direct references to all key parts of - an unique index (in whatever order). - Note that the unique keys for DISTINCT and GROUP BY should not - be the same (as long as they are unique). - - The FROM clause must contain a single non-constant table. - */ - if (tables - const_tables == 1 && (group_list || select_distinct) && - !tmp_table_param.sum_func_count && - (!join_tab[const_tables].select || - !join_tab[const_tables].select->quick || - join_tab[const_tables].select->quick->get_type() != - QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) - { - if (group_list && - list_contains_unique_index(join_tab[const_tables].table, - find_field_in_order_list, - (void *) group_list)) - { - group_list= 0; - group= 0; - } - if (select_distinct && - list_contains_unique_index(join_tab[const_tables].table, - find_field_in_item_list, - (void *) &fields_list)) - { - select_distinct= 0; - } - } if (!group_list && group) { order=0; // The output has only one row @@ -1064,6 +1083,23 @@ JOIN::optimize() { need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort } + if (order) + { + /* + Force using of tmp table if sorting by a SP or UDF function due to + their expensive and probably non-deterministic nature. + */ + for (ORDER *tmp_order= order; tmp_order ; tmp_order=tmp_order->next) + { + Item *item= *tmp_order->item; + if (item->walk(&Item::is_expensive_processor,(byte*)0)) + { + /* Force tmp table without sort */ + need_tmp=1; simple_order=simple_group=0; + break; + } + } + } } tmp_having= having; @@ -2169,6 +2205,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, int ref_changed; do { + more_const_tables_found: ref_changed = 0; found_ref=0; @@ -2180,6 +2217,30 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++) { table=s->table; + + /* + If equi-join condition by a key is null rejecting and after a + substitution of a const table the key value happens to be null + then we can state that there are no matches for this equi-join. + */ + if ((keyuse= s->keyuse) && *s->on_expr_ref) + { + while (keyuse->table == table) + { + if (!(keyuse->val->used_tables() & ~join->const_table_map) && + keyuse->val->is_null() && keyuse->null_rejecting) + { + s->type= JT_CONST; + mark_as_null_row(table); + found_const_table_map|= table->map; + join->const_table_map|= table->map; + set_position(join,const_count++,s,(KEYUSE*) 0); + goto more_const_tables_found; + } + keyuse++; + } + } + if (s->dependent) // If dependent on some table { // All dep. must be constants @@ -2230,34 +2291,38 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, } while (keyuse->table == table && keyuse->key == key); if (eq_part.is_prefix(table->key_info[key].key_parts) && - ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) == - HA_NOSAME) && !table->fulltext_searched && !table->pos_in_table_list->embedding) { - if (const_ref == eq_part) - { // Found everything for ref. - int tmp; - ref_changed = 1; - s->type= JT_CONST; - join->const_table_map|=table->map; - set_position(join,const_count++,s,start_keyuse); - if (create_ref_for_key(join, s, start_keyuse, - found_const_table_map)) - DBUG_RETURN(1); - if ((tmp=join_read_const_table(s, - join->positions+const_count-1))) - { - if (tmp > 0) - DBUG_RETURN(1); // Fatal error + if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY)) + == HA_NOSAME) + { + if (const_ref == eq_part) + { // Found everything for ref. + int tmp; + ref_changed = 1; + s->type= JT_CONST; + join->const_table_map|=table->map; + set_position(join,const_count++,s,start_keyuse); + if (create_ref_for_key(join, s, start_keyuse, + found_const_table_map)) + DBUG_RETURN(1); + if ((tmp=join_read_const_table(s, + join->positions+const_count-1))) + { + if (tmp > 0) + DBUG_RETURN(1); // Fatal error + } + else + found_const_table_map|= table->map; + break; } else - found_const_table_map|= table->map; - break; + found_ref|= refs; // Table is const if all refs are const } - else - found_ref|= refs; // Table is const if all refs are const - } + else if (const_ref == eq_part) + s->const_keys.set_bit(key); + } } } } @@ -2470,8 +2535,11 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, /* field = expression OR field IS NULL */ old->level= and_level; old->optimize= KEY_OPTIMIZE_REF_OR_NULL; - /* Remember the NOT NULL value */ - if (old->val->is_null()) + /* + Remember the NOT NULL value unless the value does not depend + on other tables. + */ + if (!old->val->used_tables() && old->val->is_null()) old->val= new_fields->val; /* The referred expression can be NULL: */ old->null_rejecting= 0; @@ -2657,7 +2725,8 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, We use null_rejecting in add_not_null_conds() to add 'othertbl.field IS NOT NULL' to tab->select_cond. */ - (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC) && + (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC || + cond->functype() == Item_func::MULT_EQUAL_FUNC) && ((*value)->type() == Item::FIELD_ITEM) && ((Item_field*)*value)->field->maybe_null()); (*key_fields)++; @@ -2757,11 +2826,12 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level, break; case Item_func::OPTIMIZE_KEY: { + Item **values; // BETWEEN, IN, NE if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM && !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) { - Item **values= cond_func->arguments()+1; + values= cond_func->arguments()+1; if (cond_func->functype() == Item_func::NE_FUNC && cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM && !(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT)) @@ -2774,6 +2844,22 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level, cond_func->argument_count()-1, usable_tables); } + if (cond_func->functype() == Item_func::BETWEEN) + { + values= cond_func->arguments(); + for (uint i= 1 ; i < cond_func->argument_count() ; i++) + { + Item_field *field_item; + if (cond_func->arguments()[i]->real_item()->type() == Item::FIELD_ITEM + && + !(cond_func->arguments()[i]->used_tables() & OUTER_REF_TABLE_BIT)) + { + field_item= (Item_field *) (cond_func->arguments()[i]->real_item()); + add_key_equal_fields(key_fields, *and_level, cond_func, + field_item, 0, values, 1, usable_tables); + } + } + } break; } case Item_func::OPTIMIZE_OP: @@ -3405,7 +3491,7 @@ best_access_path(JOIN *join, keyuse->used_tables)); if (tmp < best_prev_record_reads) { - best_part_found_ref= keyuse->used_tables; + best_part_found_ref= keyuse->used_tables & ~join->const_table_map; best_prev_record_reads= tmp; } if (rec > keyuse->ref_table_rows) @@ -5937,7 +6023,8 @@ eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab) if (tab->cached_eq_ref_table) // If cached return tab->eq_ref_table; tab->cached_eq_ref_table=1; - if (tab->type == JT_CONST) // We can skip const tables + /* We can skip const tables only if not an outer table */ + if (tab->type == JT_CONST && !tab->first_inner) return (tab->eq_ref_table=1); /* purecov: inspected */ if (tab->type != JT_EQ_REF || tab->table->maybe_null) return (tab->eq_ref_table=0); // We must use this @@ -6174,10 +6261,16 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, DBUG_RETURN(0); } - +/* + used only in JOIN::clear +*/ static void clear_tables(JOIN *join) { - for (uint i=0 ; i < join->tables ; i++) + /* + must clear only the non-const tables, as const tables + are not re-calculated. + */ + for (uint i=join->const_tables ; i < join->tables ; i++) mark_as_null_row(join->table[i]); // All fields are NULL } @@ -6453,6 +6546,7 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal) field_item= (Item_field*) right_item; const_item= left_item; } + if (const_item && field_item->result_type() == const_item->result_type()) { @@ -7110,11 +7204,14 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, Item_func::Functype functype= func->functype(); if (right_item->eq(field,0) && left_item != value && + right_item->cmp_context == field->cmp_context && (left_item->result_type() != STRING_RESULT || value->result_type() != STRING_RESULT || left_item->collation.collation == value->collation.collation)) { Item *tmp=value->new_item(); + tmp->collation.set(right_item->collation); + if (tmp) { thd->change_item_tree(args + 1, tmp); @@ -7131,11 +7228,14 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list, } } else if (left_item->eq(field,0) && right_item != value && + left_item->cmp_context == field->cmp_context && (right_item->result_type() != STRING_RESULT || value->result_type() != STRING_RESULT || right_item->collation.collation == value->collation.collation)) { Item *tmp=value->new_item(); + tmp->collation.set(left_item->collation); + if (tmp) { thd->change_item_tree(args, tmp); @@ -8034,7 +8134,12 @@ Field* create_tmp_field_from_field(THD *thd, Field* org_field, { Field *new_field; - if (convert_blob_length && (org_field->flags & BLOB_FLAG)) + /* + Make sure that the blob fits into a Field_varstring which has + 2-byte lenght. + */ + if (convert_blob_length && convert_blob_length < UINT_MAX16 && + (org_field->flags & BLOB_FLAG)) new_field= new Field_varstring(convert_blob_length, org_field->maybe_null(), org_field->field_name, table, @@ -8116,8 +8221,13 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE) new_field= item->tmp_table_field_from_field_type(table); + /* + Make sure that the blob fits into a Field_varstring which has + 2-byte lenght. + */ else if (item->max_length/item->collation.collation->mbmaxlen > 255 && - convert_blob_length) + item->max_length/item->collation.collation->mbmaxlen < UINT_MAX16 + && convert_blob_length) new_field= new Field_varstring(convert_blob_length, maybe_null, item->name, table, item->collation.collation); @@ -8884,11 +8994,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, keyinfo->key_length+= key_part_info->length; } } - else - { - set_if_smaller(table->s->max_rows, rows_limit); - param->end_write_records= rows_limit; - } if (distinct && field_count != param->hidden_field_count) { @@ -8903,8 +9008,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, null_pack_length-=hidden_null_pack_length; keyinfo->key_parts= ((field_count-param->hidden_field_count)+ test(null_pack_length)); - set_if_smaller(table->s->max_rows, rows_limit); - param->end_write_records= rows_limit; table->distinct= 1; table->s->keys= 1; if (blob_count) @@ -8956,6 +9059,20 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, 0 : FIELDFLAG_BINARY; } } + + /* + Push the LIMIT clause to the temporary table creation, so that we + materialize only up to 'rows_limit' records instead of all result records. + This optimization is not applicable when there is GROUP BY or there is + no GROUP BY, but there are aggregate functions, because both must be + computed for all result rows. + */ + if (!group && !thd->lex->current_select->with_sum_func) + { + set_if_smaller(table->s->max_rows, rows_limit); + param->end_write_records= rows_limit; + } + if (thd->is_fatal_error) // If end of memory goto err; /* purecov: inspected */ table->s->db_record_offset= 1; @@ -11447,6 +11564,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, We must not try to use disabled keys. */ usable_keys= table->s->keys_in_use; + /* we must not consider keys that are disabled by IGNORE INDEX */ + usable_keys.intersect(table->keys_in_use_for_query); for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next) { @@ -12810,7 +12929,7 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields, { if (! field->const_item()) { - Item_sum *sum_item=(Item_sum*) field; + Item_sum *sum_item=(Item_sum*) field->real_item(); if (!sum_item->quick_group) param->quick_group=0; // UDF SUM function param->sum_func_count++; @@ -13070,10 +13189,11 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, param->copy_funcs.empty(); for (i= 0; (pos= li++); i++) { - if (pos->real_item()->type() == Item::FIELD_ITEM) + Item *real_pos= pos->real_item(); + if (real_pos->type() == Item::FIELD_ITEM) { Item_field *item; - pos= pos->real_item(); + pos= real_pos; if (!(item= new Item_field(thd, ((Item_field*) pos)))) goto err; pos= item; @@ -13112,12 +13232,13 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, } } } - else if ((pos->type() == Item::FUNC_ITEM || - pos->type() == Item::SUBSELECT_ITEM || - pos->type() == Item::CACHE_ITEM || - pos->type() == Item::COND_ITEM) && - !pos->with_sum_func) + else if ((real_pos->type() == Item::FUNC_ITEM || + real_pos->type() == Item::SUBSELECT_ITEM || + real_pos->type() == Item::CACHE_ITEM || + real_pos->type() == Item::COND_ITEM) && + !real_pos->with_sum_func) { // Save for send fields + pos= real_pos; /* TODO: In most cases this result will be sent to the user. This should be changed to use copy_int or copy_real depending @@ -13308,7 +13429,9 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, { Field *field; - if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) + if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) || + (item->type() == Item::FUNC_ITEM && + ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC)) item_field= item; else { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index cabb04c5f16..eb78f4fbdae 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -250,9 +250,35 @@ bool mysqld_show_column_types(THD *thd) } -int -mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, - const char *wild, bool dir) +/* + find_files() - find files in a given directory. + + SYNOPSIS + find_files() + thd thread handler + files put found files in this list + db database name to set in TABLE_LIST structure + path path to database + wild filter for found files + dir read databases in path if TRUE, read .frm files in + database otherwise + + RETURN + FIND_FILES_OK success + FIND_FILES_OOM out of memory error + FIND_FILES_DIR no such directory, or directory can't be read +*/ + +enum find_files_result { + FIND_FILES_OK, + FIND_FILES_OOM, + FIND_FILES_DIR +}; + +static +find_files_result +find_files(THD *thd, List<char> *files, const char *db, + const char *path, const char *wild, bool dir) { uint i; char *ext; @@ -262,7 +288,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, uint col_access=thd->col_access; #endif TABLE_LIST table_list; - DBUG_ENTER("mysql_find_files"); + DBUG_ENTER("find_files"); if (wild && !wild[0]) wild=0; @@ -275,7 +301,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); else my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno); - DBUG_RETURN(-1); + DBUG_RETURN(FIND_FILES_DIR); } for (i=0 ; i < (uint) dirp->number_off_files ; i++) @@ -337,7 +363,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, if (files->push_back(thd->strdup(file->name))) { my_dirend(dirp); - DBUG_RETURN(-1); + DBUG_RETURN(FIND_FILES_OOM); } } DBUG_PRINT("info",("found: %d files", files->elements)); @@ -345,7 +371,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, VOID(ha_find_files(thd,db,path,wild,dir,files)); - DBUG_RETURN(0); + DBUG_RETURN(FIND_FILES_OK); } @@ -439,13 +465,11 @@ bool mysqld_show_create_db(THD *thd, char *dbname, { Security_context *sctx= thd->security_ctx; int length; - char path[FN_REFLEN]; char buff[2048]; String buffer(buff, sizeof(buff), system_charset_info); #ifndef NO_EMBEDDED_ACCESS_CHECKS uint db_access; #endif - bool found_libchar; HA_CREATE_INFO create; uint create_options = create_info ? create_info->options : 0; Protocol *protocol=thd->protocol; @@ -480,23 +504,13 @@ bool mysqld_show_create_db(THD *thd, char *dbname, } else { - (void) sprintf(path,"%s/%s",mysql_data_home, dbname); - length=unpack_dirname(path,path); // Convert if not unix - found_libchar= 0; - if (length && path[length-1] == FN_LIBCHAR) - { - found_libchar= 1; - path[length-1]=0; // remove ending '\' - } - if (access(path,F_OK)) + if (check_db_dir_existence(dbname)) { my_error(ER_BAD_DB_ERROR, MYF(0), dbname); DBUG_RETURN(TRUE); } - if (found_libchar) - path[length-1]= FN_LIBCHAR; - strmov(path+length, MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); + + load_db_opt_by_name(thd, dbname, &create); } List<Item> field_list; field_list.push_back(new Item_empty_string("Database",NAME_LEN)); @@ -2000,8 +2014,8 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) wild string otherwise it's db name; RETURN - 1 error - 0 success + zero success + non-zero error */ int make_db_list(THD *thd, List<char> *files, @@ -2027,8 +2041,8 @@ int make_db_list(THD *thd, List<char> *files, if (files->push_back(thd->strdup(information_schema_name.str))) return 1; } - return mysql_find_files(thd, files, NullS, mysql_data_home, - idx_field_vals->db_value, 1); + return (find_files(thd, files, NullS, mysql_data_home, + idx_field_vals->db_value, 1) != FIND_FILES_OK); } /* @@ -2055,7 +2069,8 @@ int make_db_list(THD *thd, List<char> *files, if (files->push_back(thd->strdup(information_schema_name.str))) return 1; *with_i_schema= 1; - return mysql_find_files(thd, files, NullS, mysql_data_home, NullS, 1); + return (find_files(thd, files, NullS, + mysql_data_home, NullS, 1) != FIND_FILES_OK); } @@ -2116,12 +2131,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) LINT_INIT(end); LINT_INIT(len); - /* - Let us set fake sql_command so views won't try to merge - themselves into main statement. - */ - lex->sql_command= SQLCOM_SHOW_FIELDS; - lex->reset_n_backup_query_tables_list(&query_tables_list_backup); /* @@ -2144,8 +2153,16 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) I_S tables will be done. */ thd->temporary_tables= open_tables_state_backup.temporary_tables; + /* + Let us set fake sql_command so views won't try to merge + themselves into main statement. If we don't do this, + SELECT * from information_schema.xxxx will cause problems. + SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' + */ + lex->sql_command= SQLCOM_SHOW_FIELDS; res= open_normal_and_derived_tables(thd, show_table_list, MYSQL_LOCK_IGNORE_FLUSH); + lex->sql_command= save_sql_command; /* get_all_tables() returns 1 on failure and 0 on success thus return only these and not the result code of ::process_table() @@ -2204,9 +2221,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) strxmov(path, mysql_data_home, "/", base_name, NullS); end= path + (len= unpack_dirname(path,path)); len= FN_LEN - len; - if (mysql_find_files(thd, &files, base_name, - path, idx_field_vals.table_value, 0)) - goto err; + find_files_result res= find_files(thd, &files, base_name, + path, idx_field_vals.table_value, 0); + if (res != FIND_FILES_OK) + { + /* + Downgrade errors about problems with database directory to + warnings if this is not a 'SHOW' command. Another thread + may have dropped database, and we may still have a name + for that directory. + */ + if (res == FIND_FILES_DIR && lex->orig_sql_command == SQLCOM_END) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->net.last_errno, thd->net.last_error); + thd->clear_error(); + continue; + } + else + { + goto err; + } + } if (lower_case_table_names) orig_base_name= thd->strdup(base_name); } @@ -2267,8 +2303,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first; lex->all_selects_list= &sel; lex->derived_tables= 0; + lex->sql_command= SQLCOM_SHOW_FIELDS; res= open_normal_and_derived_tables(thd, show_table_list, MYSQL_LOCK_IGNORE_FLUSH); + lex->sql_command= save_sql_command; /* We should use show_table_list->alias instead of show_table_list->table_name because table_name @@ -2319,8 +2357,11 @@ bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name, int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) { - char path[FN_REFLEN]; - bool found_libchar; + /* + TODO: fill_schema_shemata() is called when new client is connected. + Returning error status in this case leads to client hangup. + */ + INDEX_FIELD_VALUES idx_field_vals; List<char> files; char *file_name; @@ -2352,20 +2393,9 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) (grant_option && !check_grant_db(thd, file_name))) #endif { - strxmov(path, mysql_data_home, "/", file_name, NullS); - length=unpack_dirname(path,path); // Convert if not unix - found_libchar= 0; - if (length && path[length-1] == FN_LIBCHAR) - { - found_libchar= 1; - path[length-1]=0; // remove ending '\' - } + load_db_opt_by_name(thd, file_name, &create); - if (found_libchar) - path[length-1]= FN_LIBCHAR; - strmov(path+length, MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); - if (store_schema_shemata(thd, table, file_name, + if (store_schema_shemata(thd, table, file_name, create.default_table_charset)) DBUG_RETURN(1); } @@ -2683,9 +2713,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, table->field[5]->store("",0, cs); table->field[5]->set_notnull(); } - pos=(byte*) ((flags & NOT_NULL_FLAG) && - field->type() != FIELD_TYPE_TIMESTAMP ? - "NO" : "YES"); + pos=(byte*) ((flags & NOT_NULL_FLAG) ? "NO" : "YES"); table->field[6]->store((const char*) pos, strlen((const char*) pos), cs); is_blob= (field->type() == FIELD_TYPE_BLOB); @@ -3110,31 +3138,18 @@ static int get_schema_views_record(THD *thd, struct st_table_list *tables, if (tables->view) { Security_context *sctx= thd->security_ctx; - ulong grant= SHOW_VIEW_ACL; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - char *save_table_name= tables->table_name; - if (!my_strcasecmp(system_charset_info, tables->definer.user.str, - sctx->priv_user) && - !my_strcasecmp(system_charset_info, tables->definer.host.str, - sctx->priv_host)) - grant= SHOW_VIEW_ACL; - else + if (!tables->allowed_show) { - tables->table_name= tables->view_name.str; - if (check_access(thd, SHOW_VIEW_ACL , base_name, - &tables->grant.privilege, 0, 1, - test(tables->schema_table))) - grant= get_table_grant(thd, tables); - else - grant= tables->grant.privilege; + if (!my_strcasecmp(system_charset_info, tables->definer.user.str, + sctx->priv_user) && + !my_strcasecmp(system_charset_info, tables->definer.host.str, + sctx->priv_host)) + tables->allowed_show= TRUE; } - tables->table_name= save_table_name; -#endif - restore_record(table, s->default_values); table->field[1]->store(tables->view_db.str, tables->view_db.length, cs); table->field[2]->store(tables->view_name.str, tables->view_name.length, cs); - if (grant & SHOW_VIEW_ACL) + if (tables->allowed_show) { char buff[2048]; String qwe_str(buff, sizeof(buff), cs); @@ -3963,13 +3978,19 @@ bool get_schema_tables_result(JOIN *join) table_list->table->file->delete_all_rows(); free_io_cache(table_list->table); filesort_free_buffers(table_list->table); + table_list->table->null_row= 0; } else table_list->table->file->records= 0; if (table_list->schema_table->fill_table(thd, table_list, tab->select_cond)) + { result= 1; + join->error= 1; + table_list->is_schema_table_processed= TRUE; + break; + } table_list->is_schema_table_processed= TRUE; } } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 79228be8a76..7aaca809113 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -248,6 +248,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs) 0 No conversion needed 1 Either character set conversion or adding leading zeros (e.g. for UCS-2) must be done + + NOTE + to_cs may be NULL for "no conversion" if the system variable + character_set_results is NULL. */ bool String::needs_conversion(uint32 arg_length, @@ -256,7 +260,8 @@ bool String::needs_conversion(uint32 arg_length, uint32 *offset) { *offset= 0; - if ((to_cs == &my_charset_bin) || + if (!to_cs || + (to_cs == &my_charset_bin) || (to_cs == from_cs) || my_charset_same(from_cs, to_cs) || ((from_cs == &my_charset_bin) && diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4772d64ad0a..a340c5ffc98 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -715,6 +715,40 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(-1); } + /* + Convert the default value from client character + set into the column character set if necessary. + */ + if (sql_field->def && + save_cs != sql_field->def->collation.collation && + (sql_field->sql_type == FIELD_TYPE_VAR_STRING || + sql_field->sql_type == FIELD_TYPE_STRING || + sql_field->sql_type == FIELD_TYPE_SET || + sql_field->sql_type == FIELD_TYPE_ENUM)) + { + Query_arena backup_arena; + bool need_to_change_arena= !thd->stmt_arena->is_conventional(); + if (need_to_change_arena) + { + /* Asser that we don't do that at every PS execute */ + DBUG_ASSERT(thd->stmt_arena->is_first_stmt_execute() || + thd->stmt_arena->is_first_sp_execute()); + thd->set_n_backup_active_arena(thd->stmt_arena, &backup_arena); + } + + sql_field->def= sql_field->def->safe_charset_converter(save_cs); + + if (need_to_change_arena) + thd->restore_active_arena(thd->stmt_arena, &backup_arena); + + if (sql_field->def == NULL) + { + /* Could not convert */ + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(-1); + } + } + if (sql_field->sql_type == FIELD_TYPE_SET || sql_field->sql_type == FIELD_TYPE_ENUM) { @@ -776,35 +810,6 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->interval_list.empty(); // Don't need interval_list anymore } - /* - Convert the default value from client character - set into the column character set if necessary. - */ - if (sql_field->def && cs != sql_field->def->collation.collation) - { - Query_arena backup_arena; - bool need_to_change_arena= !thd->stmt_arena->is_conventional(); - if (need_to_change_arena) - { - /* Asser that we don't do that at every PS execute */ - DBUG_ASSERT(thd->stmt_arena->is_first_stmt_execute() || - thd->stmt_arena->is_first_sp_execute()); - thd->set_n_backup_active_arena(thd->stmt_arena, &backup_arena); - } - - sql_field->def= sql_field->def->safe_charset_converter(cs); - - if (need_to_change_arena) - thd->restore_active_arena(thd->stmt_arena, &backup_arena); - - if (sql_field->def == NULL) - { - /* Could not convert */ - my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); - DBUG_RETURN(-1); - } - } - if (sql_field->sql_type == FIELD_TYPE_SET) { uint32 field_length; @@ -1631,10 +1636,9 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, if (!create_info->default_table_charset) { HA_CREATE_INFO db_info; - char path[FN_REFLEN]; - /* Abuse build_table_path() to build the path to the db.opt file */ - build_table_path(path, sizeof(path), db, MY_DB_OPT_FILE, ""); - load_db_opt(thd, path, &db_info); + + load_db_opt_by_name(thd, db, &db_info); + create_info->default_table_charset= db_info.default_table_charset; } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 66a16f16d8c..6bb50d602c3 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -158,11 +158,13 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) { TABLE *table; bool result= TRUE; - LEX_STRING definer_user; - LEX_STRING definer_host; + String stmt_query; DBUG_ENTER("mysql_create_or_drop_trigger"); + /* Charset of the buffer for statement must be system one. */ + stmt_query.set_charset(system_charset_info); + /* QQ: This function could be merged in mysql_alter_table() function But do we want this ? @@ -264,8 +266,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) } result= (create ? - table->triggers->create_trigger(thd, tables, &definer_user, &definer_host): - table->triggers->drop_trigger(thd, tables)); + table->triggers->create_trigger(thd, tables, &stmt_query): + table->triggers->drop_trigger(thd, tables, &stmt_query)); end: VOID(pthread_mutex_unlock(&LOCK_open)); @@ -277,29 +279,9 @@ end: { thd->clear_error(); - String log_query(thd->query, thd->query_length, system_charset_info); - - if (create) - { - log_query.set((char *) 0, 0, system_charset_info); /* reset log_query */ - - log_query.append(STRING_WITH_LEN("CREATE ")); - - if (definer_user.str && definer_host.str) - { - /* - Append definer-clause if the trigger is SUID (a usual trigger in - new MySQL versions). - */ - - append_definer(thd, &log_query, &definer_user, &definer_host); - } - - log_query.append(thd->lex->stmt_definition_begin); - } - /* Such a statement can always go directly to binlog, no trans cache. */ - Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), 0, FALSE); + Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0, + FALSE); mysql_bin_log.write(&qinfo); } @@ -319,22 +301,8 @@ end: LEX) tables - table list containing one open table for which the trigger is created. - definer_user - [out] after a call it points to 0-terminated string or - contains the NULL-string: - - 0-terminated is returned if the trigger is SUID. The - string contains user name part of the actual trigger - definer. - - NULL-string is returned if the trigger is non-SUID. - Anyway, the caller is responsible to provide memory for - storing LEX_STRING object. - definer_host - [out] after a call it points to 0-terminated string or - contains the NULL-string: - - 0-terminated string is returned if the trigger is - SUID. The string contains host name part of the - actual trigger definer. - - NULL-string is returned if the trigger is non-SUID. - Anyway, the caller is responsible to provide memory for - storing LEX_STRING object. + stmt_query - [OUT] after successful return, this string contains + well-formed statement for creation this trigger. NOTE - Assumes that trigger name is fully qualified. @@ -349,8 +317,7 @@ end: True - error */ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, - LEX_STRING *definer_user, - LEX_STRING *definer_host) + String *stmt_query) { LEX *lex= thd->lex; TABLE *table= tables->table; @@ -358,6 +325,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigname_path[FN_REFLEN]; LEX_STRING dir, file, trigname_file; LEX_STRING *trg_def, *name; + LEX_STRING definer_user; + LEX_STRING definer_host; ulonglong *trg_sql_mode; char trg_definer_holder[USER_HOST_BUFF_SIZE]; LEX_STRING *trg_definer; @@ -505,8 +474,6 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, definers_list.push_back(trg_definer, &table->mem_root)) goto err_with_cleanup; - trg_def->str= thd->query; - trg_def->length= thd->query_length; *trg_sql_mode= thd->variables.sql_mode; #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -526,27 +493,54 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, { /* SUID trigger. */ - *definer_user= lex->definer->user; - *definer_host= lex->definer->host; + definer_user= lex->definer->user; + definer_host= lex->definer->host; trg_definer->str= trg_definer_holder; - trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@", - definer_host->str, NullS) - trg_definer->str; + trg_definer->length= strxmov(trg_definer->str, definer_user.str, "@", + definer_host.str, NullS) - trg_definer->str; } else { /* non-SUID trigger. */ - definer_user->str= 0; - definer_user->length= 0; + definer_user.str= 0; + definer_user.length= 0; - definer_host->str= 0; - definer_host->length= 0; + definer_host.str= 0; + definer_host.length= 0; trg_definer->str= (char*) ""; trg_definer->length= 0; } + /* + Create well-formed trigger definition query. Original query is not + appropriated, because definer-clause can be not truncated. + */ + + stmt_query->append(STRING_WITH_LEN("CREATE ")); + + if (trg_definer) + { + /* + Append definer-clause if the trigger is SUID (a usual trigger in + new MySQL versions). + */ + + append_definer(thd, stmt_query, &definer_user, &definer_host); + } + + stmt_query->append(thd->lex->stmt_definition_begin, + (char *) thd->lex->sphead->m_body_begin - + thd->lex->stmt_definition_begin + + thd->lex->sphead->m_body.length); + + trg_def->str= stmt_query->c_ptr(); + trg_def->length= stmt_query->length(); + + /* Create trigger definition file. */ + if (!sql_create_definition_file(&dir, &file, &triggers_file_type, (gptr)this, triggers_file_parameters, 0)) return 0; @@ -644,15 +638,19 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, SYNOPSIS drop_trigger() - thd - current thread context (including trigger definition in LEX) - tables - table list containing one open table for which trigger is - dropped. + thd - current thread context + (including trigger definition in LEX) + tables - table list containing one open table for which trigger + is dropped. + stmt_query - [OUT] after successful return, this string contains + well-formed statement for creation this trigger. RETURN VALUE False - success True - error */ -bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) +bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables, + String *stmt_query) { LEX *lex= thd->lex; LEX_STRING *name; @@ -662,6 +660,8 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) List_iterator<LEX_STRING> it_definer(definers_list); char path[FN_REFLEN]; + stmt_query->append(thd->query, thd->query_length); + while ((name= it_name++)) { it_def++; @@ -1503,40 +1503,11 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, old_field= table->field; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS - Security_context *save_ctx; - - if (sp_change_security_context(thd, sp_trigger, &save_ctx)) - return TRUE; - - /* - NOTE: TRIGGER_ACL should be used below. - */ - - if (check_global_access(thd, SUPER_ACL)) - { - sp_restore_security_context(thd, save_ctx); - return TRUE; - } - - /* - Fetch information about table-level privileges to GRANT_INFO structure for - subject table. Check of privileges that will use it and information about - column-level privileges will happen in Item_trigger_field::fix_fields(). - */ - - fill_effective_table_privileges(thd, - &subject_table_grants[event][time_type], - table->s->db, table->s->table_name); -#endif // NO_EMBEDDED_ACCESS_CHECKS - thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER); - err_status= sp_trigger->execute_function(thd, 0, 0, 0); + err_status= sp_trigger->execute_trigger + (thd, table->s->db, table->s->table_name, + &subject_table_grants[event][time_type]); thd->restore_sub_statement_state(&statement_state); - -#ifndef NO_EMBEDDED_ACCESS_CHECKS - sp_restore_security_context(thd, save_ctx); -#endif // NO_EMBEDDED_ACCESS_CHECKS } return err_status; diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index e736c3e0e1a..521905a2c56 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -92,10 +92,8 @@ public: } ~Table_triggers_list(); - bool create_trigger(THD *thd, TABLE_LIST *table, - LEX_STRING *definer_user, - LEX_STRING *definer_host); - bool drop_trigger(THD *thd, TABLE_LIST *table); + bool create_trigger(THD *thd, TABLE_LIST *table, String *stmt_query); + bool drop_trigger(THD *thd, TABLE_LIST *table, String *stmt_query); bool process_triggers(THD *thd, trg_event_type event, trg_action_time_type time_type, bool old_row_is_record1); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 8f98bab5c04..163801e2f1e 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -237,7 +237,7 @@ void udf_init() } } if (error > 0) - sql_print_error(ER(ER_GET_ERRNO), my_errno); + sql_print_error("Got unknown error: %d", my_errno); end_read_record(&read_record_info); new_thd->version--; // Force close to free memory diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 9a207845893..84b22c56cf9 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -627,7 +627,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list, &select_lex->top_join_list, table_list, conds, &select_lex->leaf_tables, - FALSE, UPDATE_ACL) || + FALSE, UPDATE_ACL, SELECT_ACL) || setup_conds(thd, table_list, select_lex->leaf_tables, conds) || select_lex->setup_ref_array(thd, order_num) || setup_order(thd, select_lex->ref_pointer_array, @@ -722,7 +722,7 @@ reopen_tables: &lex->select_lex.top_join_list, table_list, &lex->select_lex.where, &lex->select_lex.leaf_tables, FALSE, - UPDATE_ACL)) + UPDATE_ACL, SELECT_ACL)) DBUG_RETURN(TRUE); if (setup_fields_with_no_wrap(thd, 0, *fields, 1, 0, 0)) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 1561ade78af..4e2b48d9faf 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -155,6 +155,56 @@ err: DBUG_RETURN(TRUE); } +/* + Fill defined view parts + + SYNOPSIS + fill_defined_view_parts() + thd current thread. + view view to operate on + + DESCRIPTION + This function will initialize the parts of the view + definition that are not specified in ALTER VIEW + to their values from CREATE VIEW. + The view must be opened to get its definition. + We use a copy of the view when opening because we want + to preserve the original view instance. + + RETURN VALUE + TRUE can't open table + FALSE success +*/ +static bool +fill_defined_view_parts (THD *thd, TABLE_LIST *view) +{ + LEX *lex= thd->lex; + bool not_used; + TABLE_LIST decoy; + + memcpy (&decoy, view, sizeof (TABLE_LIST)); + if (!open_table(thd, &decoy, thd->mem_root, ¬_used, OPEN_VIEW_NO_PARSE) && + !decoy.view) + { + /* It's a table */ + return TRUE; + } + + if (!lex->definer) + { + view->definer.host= decoy.definer.host; + view->definer.user= decoy.definer.user; + lex->definer= &view->definer; + } + if (lex->create_view_algorithm == VIEW_ALGORITHM_UNDEFINED) + lex->create_view_algorithm= decoy.algorithm; + if (lex->create_view_suid == VIEW_SUID_DEFAULT) + lex->create_view_suid= decoy.view_suid ? + VIEW_SUID_DEFINER : VIEW_SUID_INVOKER; + + return FALSE; +} + /* Creating/altering VIEW procedure @@ -207,7 +257,15 @@ bool mysql_create_view(THD *thd, } if (mode != VIEW_CREATE_NEW) + { + if (mode == VIEW_ALTER && + fill_defined_view_parts(thd, view)) + { + res= TRUE; + goto err; + } sp_cache_invalidate(); + } if (!lex->definer) { @@ -671,8 +729,10 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.str= (char*)str.ptr(); view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query + thd->lex->create_view_select_start; - view->source.length= (thd->query_length - - thd->lex->create_view_select_start); + view->source.length= (char *)skip_rear_comments((uchar *)view->source.str, + (uchar *)thd->query + + thd->query_length) - + view->source.str; view->file_version= 1; view->calc_md5(md5); view->md5.str= md5; @@ -759,13 +819,14 @@ loop_out: thd Thread handler parser parser object table TABLE_LIST structure for filling - + flags flags RETURN 0 ok 1 error */ -bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) +bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, + uint flags) { SELECT_LEX *end, *view_select; LEX *old_lex, *lex; @@ -856,6 +917,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) table->db, table->table_name); get_default_definer(thd, &table->definer); } + if (flags & OPEN_VIEW_NO_PARSE) + { + DBUG_RETURN(FALSE); + } /* Save VIEW parameters, which will be wiped out by derived table @@ -934,7 +999,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) } } else if (!table->prelocking_placeholder && - old_lex->sql_command == SQLCOM_SHOW_CREATE) + old_lex->sql_command == SQLCOM_SHOW_CREATE && + !table->belong_to_view) { if (check_table_access(thd, SHOW_VIEW_ACL, table, 0)) goto err; @@ -994,6 +1060,31 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) table->next_global= view_tables; } + bool view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE && + lex->can_be_merged()); + TABLE_LIST *view_main_select_tables; + if (view_is_mergeable) + { + /* + Currently 'view_main_select_tables' differs from 'view_tables' + only then view has CONVERT_TZ() function in its select list. + This may change in future, for example if we enable merging of + views with subqueries in select list. + */ + view_main_select_tables= + (TABLE_LIST*)lex->select_lex.table_list.first; + + /* + Let us set proper lock type for tables of the view's main + select since we may want to perform update or insert on + view. This won't work for view containing union. But this is + ok since we don't allow insert and update on such views + anyway. + */ + for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local) + tbl->lock_type= table->lock_type; + } + /* If we are opening this view as part of implicit LOCK TABLES, then this view serves as simple placeholder and we should not continue @@ -1048,43 +1139,26 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) - VIEW SELECT allow merging - VIEW used in subquery or command support MERGE algorithm */ - if (table->algorithm != VIEW_ALGORITHM_TMPTABLE && - lex->can_be_merged() && + if (view_is_mergeable && (table->select_lex->master_unit() != &old_lex->unit || old_lex->can_use_merged()) && !old_lex->can_not_use_merged()) { - List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list); - /* - Currently 'view_main_select_tables' differs from 'view_tables' - only then view has CONVERT_TZ() function in its select list. - This may change in future, for example if we enable merging - of views with subqueries in select list. - */ - TABLE_LIST *view_main_select_tables= - (TABLE_LIST*)lex->select_lex.table_list.first; /* lex should contain at least one table */ DBUG_ASSERT(view_main_select_tables != 0); + List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list); + table->effective_algorithm= VIEW_ALGORITHM_MERGE; DBUG_PRINT("info", ("algorithm: MERGE")); table->updatable= (table->updatable_view != 0); table->effective_with_check= old_lex->get_effective_with_check(table); table->merge_underlying_list= view_main_select_tables; - /* - Let us set proper lock type for tables of the view's main select - since we may want to perform update or insert on view. This won't - work for view containing union. But this is ok since we don't - allow insert and update on such views anyway. - Also we fill correct wanted privileges. - */ - for (tbl= table->merge_underlying_list; tbl; tbl= tbl->next_local) - { - tbl->lock_type= table->lock_type; + /* Fill correct wanted privileges. */ + for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local) tbl->grant.want_privilege= top_view->grant.orig_want_privilege; - } /* prepare view context */ lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables); @@ -1226,8 +1300,11 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) DBUG_ENTER("mysql_drop_view"); char path[FN_REFLEN]; TABLE_LIST *view; - bool type= 0; + frm_type_enum type; db_type not_used; + String non_existant_views; + char *wrong_object_db= NULL, *wrong_object_name= NULL; + bool error= FALSE; for (view= views; view; view= view->next_local) { @@ -1235,8 +1312,9 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) view->table_name, reg_ext, NullS); (void) unpack_filename(path, path); VOID(pthread_mutex_lock(&LOCK_open)); - if (access(path, F_OK) || - (type= (mysql_frm_type(thd, path, ¬_used) != FRMTYPE_VIEW))) + type= FRMTYPE_ERROR; + if (access(path, F_OK) || + FRMTYPE_VIEW != (type= mysql_frm_type(thd, path, ¬_used))) { char name[FN_REFLEN]; my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); @@ -1248,25 +1326,46 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) VOID(pthread_mutex_unlock(&LOCK_open)); continue; } - if (type) - my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW"); + if (type == FRMTYPE_TABLE) + { + if (!wrong_object_name) + { + wrong_object_db= view->db; + wrong_object_name= view->table_name; + } + } else - my_error(ER_BAD_TABLE_ERROR, MYF(0), name); - goto err; + { + if (non_existant_views.length()) + non_existant_views.append(','); + non_existant_views.append(String(view->table_name,system_charset_info)); + } + VOID(pthread_mutex_unlock(&LOCK_open)); + continue; } if (my_delete(path, MYF(MY_WME))) - goto err; + error= TRUE; query_cache_invalidate3(thd, view, 0); sp_cache_invalidate(); VOID(pthread_mutex_unlock(&LOCK_open)); } + if (error) + { + DBUG_RETURN(TRUE); + } + if (wrong_object_name) + { + my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name, + "VIEW"); + DBUG_RETURN(TRUE); + } + if (non_existant_views.length()) + { + my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr()); + DBUG_RETURN(TRUE); + } send_ok(thd); DBUG_RETURN(FALSE); - -err: - VOID(pthread_mutex_unlock(&LOCK_open)); - DBUG_RETURN(TRUE); - } diff --git a/sql/sql_view.h b/sql/sql_view.h index cd61d7e9e71..b6c27a60eeb 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -19,7 +19,8 @@ bool mysql_create_view(THD *thd, enum_view_create_mode mode); -bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table); +bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, + uint flags); bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 425945f525e..30c7da220a6 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -68,6 +68,34 @@ inline Item *is_truth_value(Item *A, bool v1, bool v2) new Item_int((char *) (v1 ? "FALSE" : "TRUE"),!v1, 1)); } +#ifndef DBUG_OFF +#define YYDEBUG 1 +#else +#define YYDEBUG 0 +#endif + +#ifndef DBUG_OFF +void turn_parser_debug_on() +{ + /* + MYSQLdebug is in sql/sql_yacc.cc, in bison generated code. + Turning this option on is **VERY** verbose, and should be + used when investigating a syntax error problem only. + + The syntax to run with bison traces is as follows : + - Starting a server manually : + mysqld --debug="d,parser_debug" ... + - Running a test : + mysql-test-run.pl --mysqld="--debug=d,parser_debug" ... + + The result will be in the process stderr (var/log/master.err) + */ + + extern int yydebug; + yydebug= 1; +} +#endif + %} %union { int num; @@ -1256,6 +1284,17 @@ create_function_tail: RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys { LEX *lex=Lex; + if (lex->definer != NULL) + { + /* + DEFINER is a concept meaningful when interpreting SQL code. + UDF functions are compiled. + Using DEFINER with UDF has therefore no semantic, + and is considered a parsing error. + */ + my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER"); + YYABORT; + } lex->sql_command = SQLCOM_CREATE_FUNCTION; lex->udf.name = lex->spname->m_name; lex->udf.returns=(Item_result) $2; @@ -1285,6 +1324,7 @@ create_function_tail: sp= new sp_head(); sp->reset_thd_mem_root(YYTHD); sp->init(lex); + sp->init_sp_name(YYTHD, lex->spname); sp->m_type= TYPE_ENUM_FUNCTION; lex->sphead= sp; @@ -1339,7 +1379,7 @@ create_function_tail: YYABORT; lex->sql_command= SQLCOM_CREATE_SPFUNCTION; - sp->init_strings(YYTHD, lex, lex->spname); + sp->init_strings(YYTHD, lex); if (!(sp->m_flags & sp_head::HAS_RETURN)) { my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); @@ -1911,9 +1951,12 @@ sp_proc_stmt: sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(), lex->spcont, lex); - /* Extract the query statement from the tokenizer: - The end is either lex->tok_end or tok->ptr. */ - if (lex->ptr - lex->tok_end > 1) + /* + Extract the query statement from the tokenizer. The + end is either lex->ptr, if there was no lookahead, + lex->tok_end otherwise. + */ + if (yychar == YYEMPTY) i->m_query.length= lex->ptr - sp->m_tmp_query; else i->m_query.length= lex->tok_end - sp->m_tmp_query; @@ -3089,7 +3132,7 @@ opt_bin_mod: | BINARY { Lex->type|= BINCMP_FLAG; }; opt_bin_charset: - /* empty */ { } + /* empty */ { Lex->charset= NULL; } | ASCII_SYM { Lex->charset=&my_charset_latin1; } | UNICODE_SYM { @@ -4344,6 +4387,8 @@ simple_expr: lex->length ? atoi(lex->length) : -1, lex->dec ? atoi(lex->dec) : 0, lex->charset); + if (!$$) + YYABORT; } | CASE_SYM opt_expr WHEN_SYM when_list opt_else END { $$= new Item_func_case(* $4, $2, $5 ); } @@ -4353,6 +4398,8 @@ simple_expr: Lex->length ? atoi(Lex->length) : -1, Lex->dec ? atoi(Lex->dec) : 0, Lex->charset); + if (!$$) + YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' { $$= new Item_func_conv_charset($3,$5); } @@ -6740,17 +6787,8 @@ flush: FLUSH_SYM opt_no_write_to_binlog { LEX *lex=Lex; - if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE) - { - /* - Note that both FLUSH TABLES and FLUSH PRIVILEGES will break - execution in prelocked mode. So it is better to disable - FLUSH in stored functions and triggers completely. - */ - my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH"); - YYABORT; - } - lex->sql_command= SQLCOM_FLUSH; lex->type=0; + lex->sql_command= SQLCOM_FLUSH; + lex->type= 0; lex->no_write_to_binlog= $2; } flush_options @@ -7031,7 +7069,7 @@ text_literal: | NCHAR_STRING { $$= new Item_string($1.str,$1.length,national_charset_info); } | UNDERSCORE_CHARSET TEXT_STRING - { $$ = new Item_string($2.str,$2.length,Lex->charset); } + { $$ = new Item_string($2.str,$2.length,Lex->underscore_charset); } | text_literal TEXT_STRING_literal { ((Item_string*) $1)->append($2.str,$2.length); } ; @@ -7109,7 +7147,7 @@ literal: (String*) 0; $$= new Item_string(str ? str->ptr() : "", str ? str->length() : 0, - Lex->charset); + Lex->underscore_charset); } | UNDERSCORE_CHARSET BIN_NUM { @@ -7468,6 +7506,10 @@ user: $$->user = $1; $$->host.str= (char *) "%"; $$->host.length= 1; + + if (check_string_length(system_charset_info, &$$->user, + ER(ER_USERNAME), USERNAME_LENGTH)) + YYABORT; } | ident_or_text '@' ident_or_text { @@ -7475,6 +7517,12 @@ user: if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) YYABORT; $$->user = $1; $$->host=$3; + + if (check_string_length(system_charset_info, &$$->user, + ER(ER_USERNAME), USERNAME_LENGTH) || + check_string_length(&my_charset_latin1, &$$->host, + ER(ER_HOSTNAME), HOSTNAME_LENGTH)) + YYABORT; } | CURRENT_USER optional_braces { @@ -7822,7 +7870,12 @@ option_type_value: lex))) YYABORT; - if (lex->ptr - lex->tok_end > 1) + /* + Extract the query statement from the tokenizer. The + end is either lex->ptr, if there was no lookahead, + lex->tok_end otherwise. + */ + if (yychar == YYEMPTY) qbuff.length= lex->ptr - sp->m_tmp_query; else qbuff.length= lex->tok_end - sp->m_tmp_query; @@ -8903,8 +8956,10 @@ subselect_end: { LEX *lex=Lex; lex->pop_context(); + SELECT_LEX *child= lex->current_select; lex->current_select = lex->current_select->return_after_parsing(); lex->nest_level--; + lex->current_select->n_child_sum_items += child->n_sum_items; }; /************************************************************************** @@ -8947,15 +9002,9 @@ definer: */ YYTHD->lex->definer= 0; } - | DEFINER_SYM EQ CURRENT_USER optional_braces - { - if (! (YYTHD->lex->definer= create_default_definer(YYTHD))) - YYABORT; - } - | DEFINER_SYM EQ ident_or_text '@' ident_or_text + | DEFINER_SYM EQ user { - if (!(YYTHD->lex->definer= create_definer(YYTHD, &$3, &$5))) - YYABORT; + YYTHD->lex->definer= get_current_user(YYTHD, $3); } ; @@ -8997,11 +9046,11 @@ view_algorithm_opt: view_suid: /* empty */ - { Lex->create_view_suid= TRUE; } + { Lex->create_view_suid= VIEW_SUID_DEFAULT; } | SQL_SYM SECURITY_SYM DEFINER_SYM - { Lex->create_view_suid= TRUE; } + { Lex->create_view_suid= VIEW_SUID_DEFINER; } | SQL_SYM SECURITY_SYM INVOKER_SYM - { Lex->create_view_suid= FALSE; } + { Lex->create_view_suid= VIEW_SUID_INVOKER; } ; view_tail: @@ -9092,6 +9141,7 @@ trigger_tail: YYABORT; sp->reset_thd_mem_root(YYTHD); sp->init(lex); + sp->init_sp_name(YYTHD, $3); lex->stmt_definition_begin= $2; lex->ident.str= $7; @@ -9120,7 +9170,7 @@ trigger_tail: sp_head *sp= lex->sphead; lex->sql_command= SQLCOM_CREATE_TRIGGER; - sp->init_strings(YYTHD, lex, $3); + sp->init_strings(YYTHD, lex); /* Restore flag if it was cleared above */ if (sp->m_old_cmq) YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; @@ -9168,13 +9218,14 @@ sp_tail: my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE"); YYABORT; } - + lex->stmt_definition_begin= $2; - + /* Order is important here: new - reset - init */ sp= new sp_head(); sp->reset_thd_mem_root(YYTHD); sp->init(lex); + sp->init_sp_name(YYTHD, $3); sp->m_type= TYPE_ENUM_PROCEDURE; lex->sphead= sp; @@ -9212,7 +9263,7 @@ sp_tail: LEX *lex= Lex; sp_head *sp= lex->sphead; - sp->init_strings(YYTHD, lex, $3); + sp->init_strings(YYTHD, lex); lex->sql_command= SQLCOM_CREATE_PROCEDURE; /* Restore flag if it was cleared above */ if (sp->m_old_cmq) diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 838f547dc02..43f35c452f7 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -21,6 +21,7 @@ #ifdef HAVE_STACKTRACE #include <unistd.h> +#include <strings.h> #define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end) @@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len) } #ifdef TARGET_OS_LINUX -#define SIGRETURN_FRAME_COUNT 2 + +#ifdef __i386__ +#define SIGRETURN_FRAME_OFFSET 17 +#endif + +#ifdef __x86_64__ +#define SIGRETURN_FRAME_OFFSET 23 +#endif + +static my_bool is_nptl; + +/* Check if we are using NPTL or LinuxThreads on Linux */ +void check_thread_lib(void) +{ + char buf[5]; + +#ifdef _CS_GNU_LIBPTHREAD_VERSION + confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf)); + is_nptl = !strncasecmp(buf, "NPTL", sizeof(buf)); +#else + is_nptl = 0; +#endif +} #if defined(__alpha__) && defined(__GNUC__) /* @@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp) void print_stacktrace(gptr stack_bottom, ulong thread_stack) { uchar** fp; - uint frame_count = 0; + uint frame_count = 0, sigreturn_frame_count; #if defined(__alpha__) && defined(__GNUC__) uint32* pc; #endif @@ -100,28 +123,27 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack) Attempting backtrace. You can use the following information to find out\n\ where mysqld died. If you see no messages after this, something went\n\ terribly wrong...\n"); -#ifdef __i386__ +#ifdef __i386__ __asm __volatile__ ("movl %%ebp,%0" :"=r"(fp) :"r"(fp)); - if (!fp) - { - fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\ --fomit-frame-pointer? Aborting backtrace!\n"); - return; - } +#endif +#ifdef __x86_64__ + __asm __volatile__ ("movq %%rbp,%0" + :"=r"(fp) + :"r"(fp)); #endif #if defined(__alpha__) && defined(__GNUC__) __asm __volatile__ ("mov $30,%0" :"=r"(fp) :"r"(fp)); +#endif if (!fp) { - fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\ + fprintf(stderr, "frame pointer is NULL, did you compile with\n\ -fomit-frame-pointer? Aborting backtrace!\n"); return; } -#endif /* __alpha__ */ if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp) { @@ -151,13 +173,16 @@ terribly wrong...\n"); :"r"(pc)); #endif /* __alpha__ */ + /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */ + sigreturn_frame_count = is_nptl ? 1 : 2; + while (fp < (uchar**) stack_bottom) { -#ifdef __i386__ +#if defined(__i386__) || defined(__x86_64__) uchar** new_fp = (uchar**)*fp; - fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ? - *(fp+17) : *(fp+1)); -#endif /* __386__ */ + fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ? + *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1)); +#endif /* defined(__386__) || defined(__x86_64__) */ #if defined(__alpha__) && defined(__GNUC__) uchar** new_fp = find_prev_fp(pc, fp); diff --git a/sql/stacktrace.h b/sql/stacktrace.h index d5d1e05ef0e..527d10d70a2 100644 --- a/sql/stacktrace.h +++ b/sql/stacktrace.h @@ -19,16 +19,20 @@ extern "C" { #endif #ifdef TARGET_OS_LINUX -#if defined(HAVE_STACKTRACE) || (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) +#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) #undef HAVE_STACKTRACE #define HAVE_STACKTRACE extern char* __bss_start; extern char* heap_start; -#define init_stacktrace() { heap_start = (char*) &__bss_start; } +#define init_stacktrace() do { \ + heap_start = (char*) &__bss_start; \ + check_thread_lib(); \ + } while(0); void print_stacktrace(gptr stack_bottom, ulong thread_stack); void safe_print_str(const char* name, const char* val, int max_len); +void check_thread_lib(void); #endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */ #endif /* TARGET_OS_LINUX */ diff --git a/sql/table.cc b/sql/table.cc index e50b401df5f..054736401ff 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -121,6 +121,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, // caller can't process new .frm goto err; } + if (prgflag & OPEN_VIEW_NO_PARSE) + goto err; share->blob_ptr_size= sizeof(char*); outparam->db_stat= db_stat; @@ -1590,7 +1592,7 @@ char *get_field(MEM_ROOT *mem, Field *field) bool check_db_name(char *name) { - char *start=name; + uint name_length= 0; // name length in symbols /* Used to catch empty names and names with end space */ bool last_char_is_space= TRUE; @@ -1607,6 +1609,7 @@ bool check_db_name(char *name) name+system_charset_info->mbmaxlen); if (len) { + name_length++; name += len; continue; } @@ -1614,12 +1617,13 @@ bool check_db_name(char *name) #else last_char_is_space= *name==' '; #endif + name_length++; if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR || *name == FN_EXTCHAR) return 1; name++; } - return last_char_is_space || (uint) (name - start) > NAME_LEN; + return (last_char_is_space || name_length > NAME_LEN); } @@ -2992,13 +2996,27 @@ Field_iterator_table_ref::get_natural_column_ref() st_table_list::reinit_before_use() */ -void st_table_list::reinit_before_use(THD * /* thd */) +void st_table_list::reinit_before_use(THD *thd) { /* Reset old pointers to TABLEs: they are not valid since the tables were closed in the end of previous prepare or execute call. */ table= 0; + /* Reset is_schema_table_processed value(needed for I_S tables */ + is_schema_table_processed= FALSE; + + TABLE_LIST *embedded; /* The table at the current level of nesting. */ + TABLE_LIST *embedding= this; /* The parent nested table reference. */ + do + { + embedded= embedding; + if (embedded->prep_on_expr) + embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd); + embedding= embedded->embedding; + } + while (embedding && + embedding->nested_join->join_list.head() == embedded); } diff --git a/sql/table.h b/sql/table.h index eb34867c390..5136ac2c4db 100644 --- a/sql/table.h +++ b/sql/table.h @@ -360,6 +360,10 @@ typedef struct st_schema_table #define VIEW_ALGORITHM_TMPTABLE 1 #define VIEW_ALGORITHM_MERGE 2 +#define VIEW_SUID_INVOKER 0 +#define VIEW_SUID_DEFINER 1 +#define VIEW_SUID_DEFAULT 2 + /* view WITH CHECK OPTION parameter options */ #define VIEW_CHECK_NONE 0 #define VIEW_CHECK_LOCAL 1 @@ -569,6 +573,7 @@ typedef struct st_table_list tables. Unlike 'next_local', this in this list views are *not* leaves. Created in setup_tables() -> make_leaves_list(). */ + bool allowed_show; st_table_list *next_leaf; Item *where; /* VIEW WHERE clause condition */ Item *check_option; /* WITH CHECK OPTION condition */ @@ -677,6 +682,10 @@ typedef struct st_table_list private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); + /* + Cleanup for re-execution in a prepared statement or a stored + procedure. + */ } TABLE_LIST; class Item; diff --git a/sql/udf_example.c b/sql/udf_example.c index 62995085599..a80fce81278 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -806,6 +806,7 @@ char *reverse_lookup(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) char name_buff[256]; struct hostent tmp_hostent; + int tmp_errno; #endif struct hostent *hp; unsigned long taddr; @@ -845,7 +846,6 @@ char *reverse_lookup(UDF_INIT *initid __attribute__((unused)), UDF_ARGS *args, return 0; } #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) - int tmp_errno; if (!(hp=gethostbyaddr_r((char*) &taddr,sizeof(taddr), AF_INET, &tmp_hostent, name_buff,sizeof(name_buff), &tmp_errno))) diff --git a/sql/unireg.h b/sql/unireg.h index b932a2f320c..dfebde01338 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -147,7 +147,8 @@ #define READ_SCREENS 1024 /* Read screens, info and helpfile */ #define DELAYED_OPEN 4096 /* Open table later */ #define NO_ERR_ON_NEW_FRM 8192 /* stop error sending on new format */ - +#define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view, + but do not parse view itself */ #define SC_INFO_LENGTH 4 /* Form format constant */ #define TE_INFO_LENGTH 3 #define MTYP_NOEMPTY_BIT 128 diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt new file mode 100755 index 00000000000..0c65ce390b2 --- /dev/null +++ b/strings/CMakeLists.txt @@ -0,0 +1,12 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +ADD_LIBRARY(strings bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c + ctype-czech.c ctype-euc_kr.c ctype-eucjpms.c ctype-extra.c ctype-gb2312.c ctype-gbk.c + ctype-latin1.c ctype-mb.c ctype-simple.c ctype-sjis.c ctype-tis620.c ctype-uca.c + ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c int2str.c + is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c r_strinstr.c + str2int.c str_alloc.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c + strtod.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c xml.c + strcont.c strinstr.c) diff --git a/strings/Makefile.am b/strings/Makefile.am index 7ee115c09e5..255bc4e1518 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -53,7 +53,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc bmove_upp-sparc.s strappend-sparc.s strend-sparc.s \ strinstr-sparc.s strmake-sparc.s strmov-sparc.s \ strnmov-sparc.s strstr-sparc.s strxmov-sparc.s \ - t_ctype.h + t_ctype.h CMakeLists.txt libmystrings_a_LIBADD= conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index 0bc465f16ea..39948964a42 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -636,11 +636,11 @@ my_like_range_win1250ch(CHARSET_INFO *cs __attribute__((unused)), ptr++; /* Skip escape */ else if (*ptr == w_one || *ptr == w_many) /* '_' or '%' in SQL */ break; - *min_str = like_range_prefix_min_win1250ch[(uint)(*ptr)]; + *min_str= like_range_prefix_min_win1250ch[(uint) (uchar) (*ptr)]; if (*min_str != min_sort_char) only_min_found= 0; min_str++; - *max_str++= like_range_prefix_max_win1250ch[(uint)(*ptr)]; + *max_str++= like_range_prefix_max_win1250ch[(uint) (uchar) (*ptr)]; } if (cs->state & MY_CS_BINSORT) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index b4942072e5d..eefc4f55d35 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -677,6 +677,9 @@ fi %attr(755, root, root) %{_bindir}/ndb_show_tables %attr(755, root, root) %{_bindir}/ndb_test_platform %attr(755, root, root) %{_bindir}/ndb_config +%attr(755, root, root) %{_bindir}/ndb_error_reporter +%attr(755, root, root) %{_bindir}/ndb_size.pl +%attr(-, root, root) %{_datadir}/mysql/ndb_size.tmpl %files ndb-extra %defattr(-,root,root,0755) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100755 index 00000000000..46c42d461f3 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,9 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") + +ADD_DEFINITIONS("-DMYSQL_CLIENT") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +ADD_EXECUTABLE(mysql_client_test mysql_client_test.c) +TARGET_LINK_LIBRARIES(mysql_client_test dbug mysys mysqlclient yassl taocrypt zlib wsock32) diff --git a/tests/Makefile.am b/tests/Makefile.am index e1bc93f65b6..9f143173827 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -29,7 +29,8 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \ insert_and_repair.pl \ grant.pl grant.res test_delayed_insert.pl \ pmail.pl mail_to_db.pl table_types.pl \ - udf_test udf_test.res myisam-big-rows.tst + udf_test udf_test.res myisam-big-rows.tst \ + CMakeLists.txt bin_PROGRAMS = mysql_client_test noinst_PROGRAMS = insert_test select_test thread_test diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 5ee63cb8738..8a444590301 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -50,7 +50,6 @@ static unsigned int opt_port; static my_bool tty_password= 0, opt_silent= 0; static MYSQL *mysql= 0; -static char query[MAX_TEST_QUERY_LENGTH]; static char current_db[]= "client_test_db"; static unsigned int test_count= 0; static unsigned int opt_count= 0; @@ -123,6 +122,7 @@ static void client_disconnect(); void die(const char *file, int line, const char *expr) { fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr); + fflush(NULL); abort(); } @@ -270,6 +270,7 @@ mysql_simple_prepare(MYSQL *mysql, const char *query) static void client_connect(ulong flag) { int rc; + static char query[MAX_TEST_QUERY_LENGTH]; myheader_r("client_connect"); if (!opt_silent) @@ -327,6 +328,8 @@ static void client_connect(ulong flag) static void client_disconnect() { + static char query[MAX_TEST_QUERY_LENGTH]; + myheader_r("client_disconnect"); if (mysql) @@ -658,6 +661,7 @@ int my_stmt_result(const char *buff) static void verify_col_data(const char *table, const char *col, const char *exp_data) { + static char query[MAX_TEST_QUERY_LENGTH]; MYSQL_RES *result; MYSQL_ROW row; int rc, field= 1; @@ -1363,6 +1367,7 @@ static void test_prepare_insert_update() for (cur_query= testcase; *cur_query; cur_query++) { + char query[MAX_TEST_QUERY_LENGTH]; printf("\nRunning query: %s", *cur_query); strmov(query, *cur_query); stmt= mysql_simple_prepare(mysql, query); @@ -1397,6 +1402,7 @@ static void test_prepare_simple() { MYSQL_STMT *stmt; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_simple"); @@ -1467,6 +1473,7 @@ static void test_prepare_field_result() MYSQL_STMT *stmt; MYSQL_RES *result; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_field_result"); @@ -1518,6 +1525,7 @@ static void test_prepare_syntax() { MYSQL_STMT *stmt; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_syntax"); @@ -1559,6 +1567,7 @@ static void test_prepare() my_bool is_null[7]; char llbuf[22]; MYSQL_BIND bind[7]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare"); @@ -1732,6 +1741,7 @@ static void test_double_compare() MYSQL_RES *result; MYSQL_BIND bind[3]; ulong length[3]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_double_compare"); @@ -1814,6 +1824,7 @@ static void test_null() uint nData; MYSQL_BIND bind[2]; my_bool is_null[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_null"); @@ -1960,6 +1971,7 @@ static void test_ps_null_param() /* Execute several queries, all returning NULL in result. */ for(cur_query= queries; *cur_query; cur_query++) { + char query[MAX_TEST_QUERY_LENGTH]; strmov(query, *cur_query); stmt= mysql_simple_prepare(mysql, query); check_stmt(stmt); @@ -1991,6 +2003,7 @@ static void test_fetch_null() MYSQL_BIND bind[11]; ulong length[11]; my_bool is_null[11]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_fetch_null"); @@ -2219,6 +2232,7 @@ static void test_select() int nData= 1; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_select"); @@ -2290,6 +2304,7 @@ static void test_ps_conj_select() int32 int_data; char str_data[32]; unsigned long str_length; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_ps_conj_select"); rc= mysql_query(mysql, "drop table if exists t1"); @@ -2347,6 +2362,7 @@ static void test_bug1115() MYSQL_BIND bind[1]; ulong length[1]; char szData[11]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_bug1115"); @@ -2458,6 +2474,7 @@ static void test_bug1180() MYSQL_BIND bind[1]; ulong length[1]; char szData[11]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_select_bug"); @@ -2548,6 +2565,7 @@ static void test_bug1644() int num; my_bool isnull; int rc, i; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_bug1644"); @@ -2647,6 +2665,7 @@ static void test_select_show() { MYSQL_STMT *stmt; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_select_show"); @@ -2715,6 +2734,7 @@ static void test_simple_update() MYSQL_RES *result; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_simple_update"); @@ -2792,6 +2812,7 @@ static void test_long_data() char *data= NullS; MYSQL_RES *result; MYSQL_BIND bind[3]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data"); @@ -2878,6 +2899,7 @@ static void test_long_data_str() MYSQL_RES *result; MYSQL_BIND bind[2]; my_bool is_null[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data_str"); @@ -2970,6 +2992,7 @@ static void test_long_data_str1() MYSQL_RES *result; MYSQL_BIND bind[2]; MYSQL_FIELD *field; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data_str1"); @@ -3125,6 +3148,7 @@ static void test_long_data_bin() long length; MYSQL_RES *result; MYSQL_BIND bind[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data_bin"); @@ -3204,6 +3228,7 @@ static void test_simple_delete() MYSQL_RES *result; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_simple_delete"); @@ -3286,6 +3311,7 @@ static void test_update() MYSQL_RES *result; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_update"); @@ -3382,6 +3408,7 @@ static void test_prepare_noparam() MYSQL_STMT *stmt; int rc; MYSQL_RES *result; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_noparam"); @@ -3950,6 +3977,7 @@ static void test_fetch_date() c7 timestamp(6))"); myquery(rc); + rc= mysql_query(mysql, "SET SQL_MODE=''"); rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \ '12:49:00', \ '2002-01-02 17:46:59', \ @@ -4238,6 +4266,7 @@ static void test_prepare_ext() short sData= 10; longlong bData= 20; MYSQL_BIND bind[6]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_ext"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext"); @@ -4625,6 +4654,7 @@ static void test_stmt_close() MYSQL_RES *result; unsigned int count; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_stmt_close"); @@ -5271,6 +5301,7 @@ static void test_manual_sample() ulonglong affected_rows; MYSQL_BIND bind[3]; my_bool is_null; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_manual_sample"); @@ -5625,6 +5656,7 @@ static void test_prepare_multi_statements() { MYSQL *mysql_local; MYSQL_STMT *stmt; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_multi_statements"); if (!(mysql_local= mysql_init(NULL))) @@ -5842,6 +5874,7 @@ static void test_store_result2() int nData; ulong length; MYSQL_BIND bind[1]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_store_result2"); @@ -7121,6 +7154,7 @@ static void test_set_option() static void test_prepare_grant() { int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_grant"); @@ -8318,6 +8352,7 @@ static void test_bug19671() int rc; myheader("test_bug19671"); + mysql_query(mysql, "set sql_mode=''"); rc= mysql_query(mysql, "drop table if exists t1"); myquery(rc); @@ -8593,6 +8628,7 @@ static void test_sqlmode() MYSQL_BIND bind[2]; char c1[5], c2[5]; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_sqlmode"); @@ -8736,6 +8772,7 @@ static void test_ts() ulong length; int rc, field_count; char name; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_ts"); @@ -8886,7 +8923,7 @@ static void test_bug1500() rc= mysql_query(mysql, "DROP TABLE test_bg1500"); myquery(rc); - rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s))"); + rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM"); myquery(rc); rc= mysql_query(mysql, @@ -10407,8 +10444,9 @@ static void test_ps_i18n() const char *stmt_text; MYSQL_BIND bind_array[2]; - const char *koi8= "îÕ, ÚÁ ÒÙÂÁÌËÕ"; - const char *cp1251= "Íó, çà ðûáàëêó"; + /* Represented as numbers to keep UTF8 tools from clobbering them. */ + const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5"; + const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3"; char buf1[16], buf2[16]; ulong buf1_len, buf2_len; @@ -10962,7 +11000,8 @@ static void test_view() { rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - assert(1 == my_process_stmt_result(stmt)); + rc= my_process_stmt_result(stmt); + assert(1 == rc); } mysql_stmt_close(stmt); @@ -11004,7 +11043,8 @@ static void test_view_where() { rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - assert(4 == my_process_stmt_result(stmt)); + rc= my_process_stmt_result(stmt); + assert(4 == rc); } mysql_stmt_close(stmt); @@ -11086,7 +11126,8 @@ static void test_view_2where() rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - assert(0 == my_process_stmt_result(stmt)); + rc= my_process_stmt_result(stmt); + assert(0 == rc); mysql_stmt_close(stmt); @@ -11138,7 +11179,8 @@ static void test_view_star() { rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - assert(0 == my_process_stmt_result(stmt)); + rc= my_process_stmt_result(stmt); + assert(0 == rc); } mysql_stmt_close(stmt); @@ -11192,6 +11234,7 @@ static void test_view_insert() for (i= 0; i < 3; i++) { + int rowcount= 0; my_val= i; rc= mysql_stmt_execute(insert_stmt); @@ -11199,7 +11242,8 @@ static void test_view_insert() rc= mysql_stmt_execute(select_stmt); check_execute(select_stmt, rc); - assert(i + 1 == (int) my_process_stmt_result(select_stmt)); + rowcount= (int)my_process_stmt_result(select_stmt); + assert((i+1) == rowcount); } mysql_stmt_close(insert_stmt); mysql_stmt_close(select_stmt); @@ -11239,7 +11283,8 @@ static void test_left_join_view() { rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - assert(3 == my_process_stmt_result(stmt)); + rc= my_process_stmt_result(stmt); + assert(3 == rc); } mysql_stmt_close(stmt); @@ -11314,7 +11359,8 @@ static void test_view_insert_fields() check_execute(stmt, rc); rc= mysql_stmt_execute(stmt); check_execute(stmt, rc); - assert(1 == my_process_stmt_result(stmt)); + rc= my_process_stmt_result(stmt); + assert(1 == rc); mysql_stmt_close(stmt); rc= mysql_query(mysql, "DROP VIEW v1"); @@ -11978,6 +12024,7 @@ static void test_bug6096() rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); myquery(rc); + mysql_query(mysql, "set sql_mode=''"); stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, " " c_mediumint mediumint, c_int int, " " c_bigint bigint, c_float float, " @@ -12863,6 +12910,7 @@ static void test_bug8378() DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0); sprintf(buf, "SELECT '%s'", out); + rc=mysql_real_query(mysql, buf, strlen(buf)); myquery(rc); @@ -14865,22 +14913,31 @@ static void test_bug15613() /* Bug#17667: An attacker has the opportunity to bypass query logging. + + Note! Also tests Bug#21813, where prepared statements are used to + run queries */ static void test_bug17667() { int rc; + MYSQL_STMT *stmt; + enum query_type { QT_NORMAL, QT_PREPARED}; struct buffer_and_length { + enum query_type qt; const char *buffer; const uint length; } statements[]= { - { "drop table if exists bug17667", 29 }, - { "create table bug17667 (c varchar(20))", 37 }, - { "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 }, - { "insert into bug17667 (c) values ('NUL=\0 in value')", 50 }, - { "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 }, - { "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 }, - { "drop table bug17667", 19 }, - { NULL, 0 } }; + { QT_NORMAL, "drop table if exists bug17667", 29 }, + { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 }, + { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 }, + { QT_PREPARED, + "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, }, + { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 }, + { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 }, + { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 }, + { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 }, + { QT_NORMAL, "drop table bug17667", 19 }, + { QT_NORMAL, NULL, 0 } }; struct buffer_and_length *statement_cursor; FILE *log_file; @@ -14890,35 +14947,86 @@ static void test_bug17667() for (statement_cursor= statements; statement_cursor->buffer != NULL; statement_cursor++) { - rc= mysql_real_query(mysql, statement_cursor->buffer, - statement_cursor->length); - myquery(rc); + if (statement_cursor->qt == QT_NORMAL) + { + /* Run statement as normal query */ + rc= mysql_real_query(mysql, statement_cursor->buffer, + statement_cursor->length); + myquery(rc); + } + else if (statement_cursor->qt == QT_PREPARED) + { + /* + Run as prepared statement + + NOTE! All these queries should be in the log twice, + one time for prepare and one time for execute + */ + stmt= mysql_stmt_init(mysql); + + rc= mysql_stmt_prepare(stmt, statement_cursor->buffer, + statement_cursor->length); + check_execute(stmt, rc); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + mysql_stmt_close(stmt); + } + else + { + assert(0==1); + } } - sleep(1); /* The server may need time to flush the data to the log. */ + /* Make sure the server has written the logs to disk before reading it */ + rc= mysql_query(mysql, "flush logs"); + myquery(rc); master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1); strcpy(master_log_filename, opt_vardir); strcat(master_log_filename, "/log/master.log"); - log_file= fopen(master_log_filename, "r"); + printf("Opening '%s'\n", master_log_filename); + log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(MY_WME)); free(master_log_filename); if (log_file != NULL) { for (statement_cursor= statements; statement_cursor->buffer != NULL; statement_cursor++) { - char line_buffer[MAX_TEST_QUERY_LENGTH*2]; - /* more than enough room for the query and some marginalia. */ - - do { - memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2); + int expected_hits= 1, hits= 0; + char line_buffer[MAX_TEST_QUERY_LENGTH*2]; + /* more than enough room for the query and some marginalia. */ - DIE_UNLESS(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) != - NULL); - /* If we reach EOF before finishing the statement list, then we failed. */ + /* Prepared statments always occurs twice in log */ + if (statement_cursor->qt == QT_PREPARED) + expected_hits++; - } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2, - statement_cursor->buffer, statement_cursor->length) == NULL); + /* Loop until we found expected number of log entries */ + do { + /* Loop until statement is found in log */ + do { + memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2); + + if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL) + { + /* If fgets returned NULL, it indicates either error or EOF */ + if (feof(log_file)) + DIE("Found EOF before all statements where found"); + + fprintf(stderr, "Got error %d while reading from file\n", + ferror(log_file)); + DIE("Read error"); + } + + } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2, + statement_cursor->buffer, + statement_cursor->length) == NULL); + hits++; + } while (hits < expected_hits); + + printf("Found statement starting with \"%s\"\n", + statement_cursor->buffer); } printf("success. All queries found intact in the log.\n"); @@ -14933,7 +15041,7 @@ static void test_bug17667() } if (log_file != NULL) - fclose(log_file); + my_fclose(log_file, MYF(0)); } @@ -15027,6 +15135,65 @@ static void test_bug20152() } } +/* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */ + +static void test_bug15752() +{ + MYSQL mysql_local; + int rc, i; + const int ITERATION_COUNT= 100; + char *query= "CALL p1()"; + + myheader("test_bug15752"); + + rc= mysql_query(mysql, "drop procedure if exists p1"); + myquery(rc); + rc= mysql_query(mysql, "create procedure p1() select 1"); + myquery(rc); + + mysql_init(&mysql_local); + if (! mysql_real_connect(&mysql_local, opt_host, opt_user, + opt_password, current_db, opt_port, + opt_unix_socket, + CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS)) + { + printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local)); + DIE_UNLESS(0); + } + rc= mysql_real_query(&mysql_local, query, strlen(query)); + myquery(rc); + mysql_free_result(mysql_store_result(&mysql_local)); + + rc= mysql_real_query(&mysql_local, query, strlen(query)); + DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC); + + if (! opt_silent) + printf("Got error (as expected): %s\n", mysql_error(&mysql_local)); + + /* Check some other commands too */ + + DIE_UNLESS(mysql_next_result(&mysql_local) == 0); + mysql_free_result(mysql_store_result(&mysql_local)); + DIE_UNLESS(mysql_next_result(&mysql_local) == -1); + + /* The second problem is not reproducible: add the test case */ + for (i = 0; i < ITERATION_COUNT; i++) + { + if (mysql_real_query(&mysql_local, query, strlen(query))) + { + printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local)); + break; + } + mysql_free_result(mysql_store_result(&mysql_local)); + DIE_UNLESS(mysql_next_result(&mysql_local) == 0); + mysql_free_result(mysql_store_result(&mysql_local)); + DIE_UNLESS(mysql_next_result(&mysql_local) == -1); + + } + mysql_close(&mysql_local); + rc= mysql_query(mysql, "drop procedure p1"); + myquery(rc); +} /* Bug#21206: memory corruption when too many cursors are opened at once @@ -15342,7 +15509,8 @@ static struct my_tests_st my_tests[]= { { "test_bug20152", test_bug20152 }, { "test_bug14169", test_bug14169 }, { "test_bug17667", test_bug17667 }, - { "test_bug19671", test_bug19671}, + { "test_bug19671", test_bug19671 }, + { "test_bug15752", test_bug15752 }, { "test_bug21206", test_bug21206}, { 0, 0 } }; diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt new file mode 100755 index 00000000000..a3cbb304289 --- /dev/null +++ b/vio/CMakeLists.txt @@ -0,0 +1,6 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") + +ADD_DEFINITIONS(-DUSE_SYMDIR) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/extra/yassl/include) +ADD_LIBRARY(vio vio.c viosocket.c viossl.c viosslfactories.c) diff --git a/vio/Makefile.am b/vio/Makefile.am index e89191d57cd..cb70501046e 100644 --- a/vio/Makefile.am +++ b/vio/Makefile.am @@ -38,6 +38,6 @@ test_sslclient_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ ../mysys/libmysys.a ../strings/libmystrings.a \ $(openssl_libs) $(yassl_libs) libvio_a_SOURCES= vio.c viosocket.c viossl.c viosslfactories.c - +EXTRA_DIST= CMakeLists.txt # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/vio/viosocket.c b/vio/viosocket.c index 710f7a93607..3ce1c994d79 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -276,7 +276,7 @@ int vio_close(Vio * vio) if (vio->type != VIO_CLOSED) { DBUG_ASSERT(vio->sd >= 0); - if (shutdown(vio->sd,2)) + if (shutdown(vio->sd, SHUT_RDWR)) r= -1; if (closesocket(vio->sd)) r= -1; @@ -379,16 +379,30 @@ my_bool vio_poll_read(Vio *vio,uint timeout) } -void vio_timeout(Vio *vio __attribute__((unused)), - uint which __attribute__((unused)), - uint timeout __attribute__((unused))) +void vio_timeout(Vio *vio, uint which, uint timeout) { +/* TODO: some action should be taken if socket timeouts are not supported. */ +#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) + #ifdef __WIN__ - ulong wait_timeout= (ulong) timeout * 1000; - (void) setsockopt(vio->sd, SOL_SOCKET, - which ? SO_SNDTIMEO : SO_RCVTIMEO, (char*) &wait_timeout, - sizeof(wait_timeout)); -#endif /* __WIN__ */ + + /* Windows expects time in milliseconds as int. */ + int wait_timeout= (int) timeout * 1000; + +#else /* ! __WIN__ */ + + /* POSIX specifies time as struct timeval. */ + struct timeval wait_timeout; + wait_timeout.tv_sec= timeout; + wait_timeout.tv_usec= 0; + +#endif /* ! __WIN__ */ + + /* TODO: return value should be checked. */ + (void) setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO, + (char*) &wait_timeout, sizeof(wait_timeout)); + +#endif /* defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) */ } @@ -545,9 +559,13 @@ int vio_write_shared_memory(Vio * vio, const gptr buf, int size) } +/** + Close shared memory and DBUG_PRINT any errors that happen on closing. + @return Zero if all closing functions succeed, and nonzero otherwise. +*/ int vio_close_shared_memory(Vio * vio) { - int r; + int error_count= 0; DBUG_ENTER("vio_close_shared_memory"); if (vio->type != VIO_CLOSED) { @@ -561,23 +579,44 @@ int vio_close_shared_memory(Vio * vio) result if they are success. */ if (UnmapViewOfFile(vio->handle_map) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("UnmapViewOfFile() failed")); + } if (CloseHandle(vio->event_server_wrote) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("CloseHandle(vio->esw) failed")); + } if (CloseHandle(vio->event_server_read) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("CloseHandle(vio->esr) failed")); + } if (CloseHandle(vio->event_client_wrote) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("CloseHandle(vio->ecw) failed")); + } if (CloseHandle(vio->event_client_read) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("CloseHandle(vio->ecr) failed")); + } if (CloseHandle(vio->handle_file_map) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("CloseHandle(vio->hfm) failed")); + } if (CloseHandle(vio->event_conn_closed) == 0) + { + error_count++; DBUG_PRINT("vio_error", ("CloseHandle(vio->ecc) failed")); + } } vio->type= VIO_CLOSED; vio->sd= -1; - DBUG_RETURN(!r); + DBUG_RETURN(error_count); } #endif /* HAVE_SMEM */ #endif /* __WIN__ */ diff --git a/win/Makefile.am b/win/Makefile.am new file mode 100755 index 00000000000..05c01b61360 --- /dev/null +++ b/win/Makefile.am @@ -0,0 +1,21 @@ +# Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +## Process this file with automake to create Makefile.in +EXTRA_DIST = build-vs71.bat build-vs8.bat build-vs8_x64.bat configure.js README + +# Don't update the files from bitkeeper +%::SCCS/s.% diff --git a/win/README b/win/README new file mode 100644 index 00000000000..cbda33e1184 --- /dev/null +++ b/win/README @@ -0,0 +1,82 @@ +Windows building readme +====================================== + +----------------IMPORTANT---------------------------- +This readme outlines the instructions for building +MySQL for Windows staring from version 5.0. +This readme does not apply to MySQL versions 5.1 +or ealier. +----------------------------------------------------- + +The Windows build system uses a tool named CMake to generate build files for +a variety of project systems. This tool is combined with a set of jscript +files to enable building of MySQL for Windows directly out of a bk clone. +The steps required are below. + +Step 1 +------ +Download and install CMake. It can be downloaded from http://www.cmake.org. +Once it is installed, modify your path to make sure you can execute +the cmake binary. + +Step 2 +------ +Download and install bison for Windows. It can be downloaded from +http://gnuwin32.sourceforge.net/packages/bison.htm. Please download using +the link named "Complete package, excluding sources". This includes an +installer that will install bison. After the installer finishes, modify +your path so that you can execute bison. + +Step 3 +------ +Clone your bk tree to any location you like. + +Step 4 +------ +From the root of your bk clone, execute the command: win\configure <options>. +The options right now are + + WITH_INNOBASE_STORAGE_ENGINE Enable particular storage engines + WITH_PARTITION_STORAGE_ENGINE + WITH_ARCHIVE_STORAGE_ENGINE + WITH_BERKELEY_STORAGE_ENGINE + WITH_BLACKHOLE_STORAGE_ENGINE + WITH_EXAMPLE_STORAGE_ENGINE + WITH_FEDERATED_STORAGE_ENGINE + WITH_INNOBASE_STORAGE_ENGINE + __NT__ Enable named pipe support + MYSQL_SERVER_SUFFIX=<suffix> Server suffix, default none + COMPILATION_COMMENT=<comment> Server comment, default "Source distribution" + MYSQL_TCP_PORT=<port> Server port, default 3306 + CYBOZU + +So the command line could look like: + +win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro + +Step 5 +------ +From the root of your bk clone, execute one of the batch files to generate the type +of project files you desire. + +For Visual Studio 8, do win\build-vs8. +For Visual Studio 7.1, do win\build-vs71. + +We will support building with nmake in the near future. + +Step 6 +------ +From the root of your bk clone, start your build. + +For Visual Studio, simply execute mysql.sln. This will start the IDE and you can +click the build solution menu option. + +Current issues +-------------- +1. After changing configuration (eg. adding or removing a storage engine), it +may be necessary to clean the build tree to remove any stale objects. + +2. To use Visual C++ Express Edition you also need to install the Platform SDK. +Please see this link: http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/ +At step 4 you only need to add the libraries advapi32.lib and user32.lib to +the file "corewin_express.vsprops" in order to avoid link errors. diff --git a/win/build-vs71.bat b/win/build-vs71.bat new file mode 100755 index 00000000000..959067695c5 --- /dev/null +++ b/win/build-vs71.bat @@ -0,0 +1,7 @@ +@echo off + +if exist cmakecache.txt del cmakecache.txt +copy win\vs71cache.txt cmakecache.txt +cmake -G "Visual Studio 7 .NET 2003" +copy cmakecache.txt win\vs71cache.txt + diff --git a/win/build-vs8.bat b/win/build-vs8.bat new file mode 100755 index 00000000000..d9c06241a9b --- /dev/null +++ b/win/build-vs8.bat @@ -0,0 +1,6 @@ +@echo off + +if exist cmakecache.txt del cmakecache.txt +copy win\vs8cache.txt cmakecache.txt +cmake -G "Visual Studio 8 2005" +copy cmakecache.txt win\vs8cache.txt diff --git a/win/build-vs8_x64.bat b/win/build-vs8_x64.bat new file mode 100755 index 00000000000..f1d96116390 --- /dev/null +++ b/win/build-vs8_x64.bat @@ -0,0 +1,6 @@ +@echo off + +if exist cmakecache.txt del cmakecache.txt +copy win\vs8cache.txt cmakecache.txt +cmake -G "Visual Studio 8 2005 Win64" +copy cmakecache.txt win\vs8cache.txt diff --git a/win/configure.js b/win/configure.js new file mode 100755 index 00000000000..ef90ce982a6 --- /dev/null +++ b/win/configure.js @@ -0,0 +1,166 @@ +// Configure.js + +ForReading = 1; +ForWriting = 2; +ForAppending = 8; + +try +{ + var fso = new ActiveXObject("Scripting.FileSystemObject"); + + var args = WScript.Arguments + + // read in the Unix configure.in file + var configureInTS = fso.OpenTextFile("configure.in", ForReading); + var configureIn = configureInTS.ReadAll(); + configureInTS.Close(); + var default_comment = "Source distribution"; + var default_port = GetValue(configureIn, "MYSQL_TCP_PORT_DEFAULT"); + + var configfile = fso.CreateTextFile("win\\configure.data", true); + for (i=0; i < args.Count(); i++) + { + var parts = args.Item(i).split('='); + switch (parts[0]) + { + case "WITH_ARCHIVE_STORAGE_ENGINE": + case "WITH_BERKELEY_STORAGE_ENGINE": + case "WITH_BLACKHOLE_STORAGE_ENGINE": + case "WITH_EXAMPLE_STORAGE_ENGINE": + case "WITH_FEDERATED_STORAGE_ENGINE": + case "WITH_INNOBASE_STORAGE_ENGINE": + case "WITH_PARTITION_STORAGE_ENGINE": + case "__NT__": + case "CYBOZU": + configfile.WriteLine("SET (" + args.Item(i) + " TRUE)"); + break; + case "MYSQL_SERVER_SUFFIX": + configfile.WriteLine("SET (" + parts[0] + " \"" + + parts[1] + "\")"); + break; + case "COMPILATION_COMMENT": + default_comment = parts[1]; + break; + case "MYSQL_TCP_PORT": + default_port = parts[1]; + break; + } + } + + configfile.WriteLine("SET (COMPILATION_COMMENT \"" + + default_comment + "\")"); + + configfile.WriteLine("SET (PROTOCOL_VERSION \"" + + GetValue(configureIn, "PROTOCOL_VERSION") + "\")"); + configfile.WriteLine("SET (DOT_FRM_VERSION \"" + + GetValue(configureIn, "DOT_FRM_VERSION") + "\")"); + configfile.WriteLine("SET (MYSQL_TCP_PORT \"" + default_port + "\")"); + configfile.WriteLine("SET (MYSQL_UNIX_ADDR \"" + + GetValue(configureIn, "MYSQL_UNIX_ADDR_DEFAULT") + "\")"); + var version = GetVersion(configureIn); + configfile.WriteLine("SET (VERSION \"" + version + "\")"); + configfile.WriteLine("SET (MYSQL_BASE_VERSION \"" + + GetBaseVersion(version) + "\")"); + configfile.WriteLine("SET (MYSQL_VERSION_ID \"" + + GetVersionId(version) + "\")"); + + configfile.Close(); + + //ConfigureBDB(); + + fso = null; + + WScript.Echo("done!"); +} +catch (e) +{ + WScript.Echo("Error: " + e.description); +} + +function GetValue(str, key) +{ + var pos = str.indexOf(key+'='); + if (pos == -1) return null; + pos += key.length + 1; + var end = str.indexOf("\n", pos); + if (str.charAt(pos) == "\"") + pos++; + if (str.charAt(end-1) == "\"") + end--; + return str.substring(pos, end); +} + +function GetVersion(str) +{ + var key = "AM_INIT_AUTOMAKE(mysql, "; + var pos = str.indexOf(key); //5.0.6-beta) + if (pos == -1) return null; + pos += key.length; + var end = str.indexOf(")", pos); + if (end == -1) return null; + return str.substring(pos, end); +} + +function GetBaseVersion(version) +{ + var dot = version.indexOf("."); + if (dot == -1) return null; + dot = version.indexOf(".", dot+1); + if (dot == -1) dot = version.length; + return version.substring(0, dot); +} + +function GetVersionId(version) +{ + var dot = version.indexOf("."); + if (dot == -1) return null; + var major = parseInt(version.substring(0, dot), 10); + + dot++; + var nextdot = version.indexOf(".", dot); + if (nextdot == -1) return null; + var minor = parseInt(version.substring(dot, nextdot), 10); + dot = nextdot+1; + + var stop = version.indexOf("-", dot); + if (stop == -1) stop = version.length; + var build = parseInt(version.substring(dot, stop), 10); + + var id = major; + if (minor < 10) + id += '0'; + id += minor; + if (build < 10) + id += '0'; + id += build; + return id; +} + +function ConfigureBDB() +{ + // read in the Unix configure.in file + var dbIncTS = fso.OpenTextFile("..\\bdb\\dbinc\\db.in", ForReading); + var dbIn = dbIncTS.ReadAll(); + dbIncTS.Close(); + + dbIn = dbIn.replace("@DB_VERSION_MAJOR@", "$DB_VERSION_MAJOR"); + dbIn = dbIn.replace("@DB_VERSION_MINOR@", "$DB_VERSION_MINOR"); + dbIn = dbIn.replace("@DB_VERSION_PATCH@", "$DB_VERSION_PATCH"); + dbIn = dbIn.replace("@DB_VERSION_STRING@", "$DB_VERSION_STRING"); + + dbIn = dbIn.replace("@u_int8_decl@", "typedef unsigned char u_int8_t;"); + dbIn = dbIn.replace("@int16_decl@", "typedef short int16_t;"); + dbIn = dbIn.replace("@u_int16_decl@", "typedef unsigned short u_int16_t;"); + dbIn = dbIn.replace("@int32_decl@", "typedef int int32_t;"); + dbIn = dbIn.replace("@u_int32_decl@", "typedef unsigned int u_int32_t;"); + + dbIn = dbIn.replace("@u_char_decl@", "{\r\n#if !defined(_WINSOCKAPI_)\r\n" + + "typedef unsigned char u_char;"); + dbIn = dbIn.replace("@u_short_decl@", "typedef unsigned short u_short;"); + dbIn = dbIn.replace("@u_int_decl@", "typedef unsigned int u_int;"); + dbIn = dbIn.replace("@u_long_decl@", "typedef unsigned long u_long;"); + + dbIn = dbIn.replace("@ssize_t_decl@", "#endif\r\n#if defined(_WIN64)\r\n" + + "typedef __int64 ssize_t;\r\n#else\r\n" + + "typedef int ssize_t;\r\n#endif"); +} diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt new file mode 100755 index 00000000000..53560adf6d1 --- /dev/null +++ b/zlib/CMakeLists.txt @@ -0,0 +1,8 @@ +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") +SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG") + +ADD_DEFINITIONS(-DUSE_TLS -DMYSQL_CLIENT -D__WIN32__) +ADD_LIBRARY(zlib adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio.c infback.c inffast.c inffast.h + inffixed.h inflate.c inflate.h inftrees.c inftrees.h trees.c trees.h uncompr.c zconf.h zlib.h + zutil.c zutil.h) +
\ No newline at end of file diff --git a/zlib/Makefile.am b/zlib/Makefile.am index 71619ce40c1..0081c93a2ae 100644 --- a/zlib/Makefile.am +++ b/zlib/Makefile.am @@ -29,5 +29,5 @@ libz_la_SOURCES= adler32.c compress.c crc32.c deflate.c gzio.c \ infback.c inffast.c inflate.c inftrees.c trees.c \ uncompr.c zutil.c -EXTRA_DIST= README FAQ INDEX ChangeLog algorithm.txt zlib.3 +EXTRA_DIST= README FAQ INDEX ChangeLog algorithm.txt zlib.3 CMakeLists.txt |