summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore1
-rwxr-xr-xBUILD/SETUP.sh12
-rwxr-xr-xBUILD/check-cpu355
-rwxr-xr-xBUILD/compile-ndb-autotest19
-rw-r--r--client/mysqldump.c16
-rw-r--r--myisam/mi_check.c9
-rw-r--r--mysql-test/Makefile.am7
-rw-r--r--mysql-test/lib/mtr_cases.pl22
-rw-r--r--mysql-test/lib/mtr_match.pl17
-rw-r--r--mysql-test/lib/mtr_misc.pl18
-rwxr-xr-xmysql-test/mysql-test-run.pl33
-rw-r--r--mysql-test/r/ctype_ucs.result39
-rw-r--r--mysql-test/r/delete.result4
-rw-r--r--mysql-test/r/func_gconcat.result4
-rw-r--r--mysql-test/r/func_group.result24
-rw-r--r--mysql-test/r/func_time.result23
-rw-r--r--mysql-test/r/insert_update.result26
-rw-r--r--mysql-test/r/limit.result14
-rw-r--r--mysql-test/r/myisam.result4
-rw-r--r--mysql-test/r/mysqldump.result27
-rw-r--r--mysql-test/r/ps.result47
-rw-r--r--mysql-test/r/subselect.result33
-rw-r--r--mysql-test/r/type_date.result10
-rw-r--r--mysql-test/t/ctype_ucs.test29
-rw-r--r--mysql-test/t/delete.test10
-rw-r--r--mysql-test/t/func_group.test14
-rw-r--r--mysql-test/t/func_time.test22
-rw-r--r--mysql-test/t/insert_update.test23
-rw-r--r--mysql-test/t/limit.test10
-rw-r--r--mysql-test/t/myisam.test10
-rw-r--r--mysql-test/t/mysqldump.test8
-rw-r--r--mysql-test/t/ps.test52
-rw-r--r--mysql-test/t/subselect.test26
-rw-r--r--mysql-test/t/type_date.test11
-rw-r--r--mysys/my_chsize.c4
-rw-r--r--mysys/my_read.c47
-rw-r--r--ndb/include/ndbapi/NdbOperation.hpp2
-rw-r--r--ndb/src/kernel/blocks/ERROR_codes.txt3
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihMain.cpp1
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp15
-rw-r--r--ndb/src/kernel/blocks/dbtc/Dbtc.hpp4
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp159
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp10
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp30
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp16
-rw-r--r--ndb/src/ndbapi/NdbScanOperation.cpp13
-rw-r--r--ndb/test/ndbapi/testIndex.cpp52
-rw-r--r--ndb/test/ndbapi/testSystemRestart.cpp47
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt4
-rw-r--r--sql/field.h2
-rw-r--r--sql/item.h6
-rw-r--r--sql/item_cmpfunc.cc137
-rw-r--r--sql/log.cc9
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/opt_range.cc14
-rw-r--r--sql/opt_range.h4
-rw-r--r--sql/opt_sum.cc4
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_select.cc59
-rw-r--r--sql/sql_yacc.yy7
-rw-r--r--sql/unireg.cc39
-rw-r--r--support-files/mysql.spec.sh2
-rw-r--r--tests/mysql_client_test.c5
65 files changed, 1197 insertions, 491 deletions
diff --git a/.bzrignore b/.bzrignore
index 6dd06504096..4325a9177fa 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1059,3 +1059,4 @@ vio/test-sslserver
vio/viotest-ssl
libmysql/libmysql.ver
libmysqld/sql_locale.cc
+mysql-test/mtr
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 3f8a9ccaf22..285ed0ec402 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
@@ -109,12 +109,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 b970a4b9a5b..e207d12d972 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -3,203 +3,206 @@
# 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*Mobile*)
- cpu_arg="pentium3m";
- ;;
- *Pentium*III*)
- cpu_arg="pentium3";
- ;;
- *Pentium*M*pro*)
- cpu_arg="pentium-m";
- ;;
- *Athlon*64*)
- cpu_arg="athlon64";
+ *Pentium*III*)
+ cpu_arg="pentium3";
;;
- *Athlon*)
- cpu_arg="athlon";
+ *Pentium*M*pro*)
+ cpu_arg="pentium-m";
;;
+ *Athlon*64*)
+ cpu_arg="athlon64";
+ ;;
+ *Athlon*)
+ cpu_arg="athlon";
+ ;;
- # 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'
- ;;
- *)
- 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/[^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'
+ ;;
+ *)
+ 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/client/mysqldump.c b/client/mysqldump.c
index 58e51b9b955..7f495ccdafb 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -783,8 +783,8 @@ static int get_options(int *argc, char ***argv)
static void DBerror(MYSQL *mysql, const char *when)
{
DBUG_ENTER("DBerror");
- 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);
safe_exit(EX_MYSQLERR);
DBUG_VOID_RETURN;
} /* DBerror */
@@ -811,9 +811,9 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
if (mysql_query(mysql_con, query) ||
(res && !((*res)= mysql_store_result(mysql_con))))
{
- my_printf_error(0, "%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));
return 1;
}
return 0;
@@ -1705,13 +1705,19 @@ static void dumpTable(uint numFields, char *table)
check_io(md_result_file);
}
if (mysql_query_with_error_report(sock, 0, query))
+ {
DBerror(sock, "when retrieving data from server");
+ goto err;
+ }
if (quick)
res=mysql_use_result(sock);
else
res=mysql_store_result(sock);
if (!res)
+ {
DBerror(sock, "when retrieving data from server");
+ goto err;
+ }
if (verbose)
fprintf(stderr, "-- Retrieving rows...\n");
if (mysql_num_fields(res) != numFields)
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 1374cb05094..301becf9c62 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -1369,7 +1369,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
- if (filecopy(param,new_file,info->dfile,0L,new_header_length,
+ if (new_header_length &&
+ filecopy(param,new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
info->s->state.dellink= HA_OFFSET_ERROR;
@@ -2066,7 +2067,8 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
- if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+ if (new_header_length &&
+ filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
@@ -2434,7 +2436,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
param->temp_filename);
goto err;
}
- if (filecopy(param, new_file,info->dfile,0L,new_header_length,
+ if (new_header_length &&
+ filecopy(param, new_file,info->dfile,0L,new_header_length,
"datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index cd939417e64..1e6eb12f7b2 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 $(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 \
@@ -105,6 +105,11 @@ std_data/server-cert.pem:
std_data/server-key.pem:
@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/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl
index 3666c1aa01b..650fb79155d 100644
--- a/mysql-test/lib/mtr_cases.pl
+++ b/mysql-test/lib/mtr_cases.pl
@@ -193,6 +193,28 @@ sub collect_one_test_case($$$$$$) {
$tinfo->{'slave_restart'}= 1;
}
+ # Cluster is needed by test case if testname contains ndb
+ if ( defined mtr_match_substring($tname,"ndb") )
+ {
+ $tinfo->{'ndb_test'}= 1;
+ if ( $::opt_skip_ndbcluster )
+ {
+ # Skip all ndb tests
+ $tinfo->{'skip'}= 1;
+ return;
+ }
+ if ( ! $::opt_with_ndbcluster )
+ {
+ # Ndb is not supported, skip them
+ $tinfo->{'skip'}= 1;
+ return;
+ }
+ }
+ else
+ {
+ $tinfo->{'ndb_test'}= 0;
+ }
+
# FIXME what about embedded_server + ndbcluster, skip ?!
my $master_opt_file= "$testdir/$tname-master.opt";
diff --git a/mysql-test/lib/mtr_match.pl b/mysql-test/lib/mtr_match.pl
index eb5de655520..66b639c7f8e 100644
--- a/mysql-test/lib/mtr_match.pl
+++ b/mysql-test/lib/mtr_match.pl
@@ -50,6 +50,23 @@ sub mtr_match_extension ($$) {
}
+# Match a substring anywere in a string
+
+sub mtr_match_substring ($$) {
+ my $string= shift;
+ my $substring= shift;
+
+ if ( $string =~ /(.*)\Q$substring\E(.*)$/ ) # strncmp
+ {
+ return $1;
+ }
+ else
+ {
+ return undef; # NULL
+ }
+}
+
+
sub mtr_match_any_exact ($$) {
my $string= shift;
my $mlist= shift;
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index 26d5b9ed283..08c99e90906 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -82,7 +82,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 )
{
@@ -99,7 +106,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/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 8cf14faec0c..d1e049ff883 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -233,6 +233,7 @@ our $opt_result_ext;
our $opt_skip;
our $opt_skip_rpl;
+our $opt_skip_im; # --skip-im on command line will just be ignored
our $opt_skip_test;
our $opt_sleep;
@@ -519,6 +520,7 @@ sub command_line_setup () {
'do-test=s' => \$opt_do_test,
'suite=s' => \$opt_suite,
'skip-rpl' => \$opt_skip_rpl,
+ 'skip-im' => \$opt_skip_im,
'skip-test=s' => \$opt_skip_test,
# Specify ports
@@ -898,7 +900,8 @@ sub executable_setup () {
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt",
"$path_client_bindir/mysqld",
"$path_client_bindir/mysqld-debug",
- "$path_client_bindir/mysqld-max");
+ "$path_client_bindir/mysqld-max",
+ "$path_client_bindir/mysqld-max-nt");
$path_language= mtr_path_exists("$glob_basedir/share/english/");
$path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets");
$exe_my_print_defaults=
@@ -1581,6 +1584,16 @@ sub run_testcase ($) {
{
$do_restart= 1; # Always restart if script to run
}
+ elsif ( $tinfo->{'ndb_test'} and $master->[0]->{'ndbcluster'} == 1 )
+ {
+ $do_restart= 1; # Restart with cluster
+ # print "Restarting because cluster need to be enabled\n";
+ }
+ elsif ($tinfo->{'ndb_test'} == 0 and $master->[0]->{'ndbcluster'} == 0)
+ {
+ $do_restart= 1; # Restart without cluster
+ # print "Restarting because cluster need to be disabled\n";
+ }
elsif ( $master->[0]->{'running_master_is_special'} and
$master->[0]->{'running_master_is_special'}->{'timezone'} eq
$tinfo->{'timezone'} and
@@ -1646,7 +1659,7 @@ sub run_testcase ($) {
if ( ! $opt_local_master )
{
- if ( $master->[0]->{'ndbcluster'} )
+ if ( $master->[0]->{'ndbcluster'} && $tinfo->{'ndb_test'})
{
$master->[0]->{'ndbcluster'}= ndbcluster_start();
if ( $master->[0]->{'ndbcluster'} )
@@ -1659,8 +1672,22 @@ sub run_testcase ($) {
{
# FIXME not correct location for do_before_start_master()
do_before_start_master($tname,$tinfo->{'master_sh'});
+
+ # Save skip_ndbcluster
+ my $save_opt_skip_ndbcluster= $opt_skip_ndbcluster;
+ if (!$tinfo->{'ndb_test'})
+ {
+ # Modify skip_ndbcluster so cluster is skipped for this
+ # and subsequent testcases(until we find one that does not cluster)
+ $opt_skip_ndbcluster= 1;
+ }
+
$master->[0]->{'pid'}=
mysqld_start('master',0,$tinfo->{'master_opt'},[]);
+
+ # Restore skip_ndbcluster
+ $opt_skip_ndbcluster= $save_opt_skip_ndbcluster;
+
if ( ! $master->[0]->{'pid'} )
{
report_failure_and_restart($tinfo);
@@ -2026,7 +2053,7 @@ sub mysqld_arguments ($$$$$) {
}
}
- if ( $opt_with_ndbcluster )
+ if ( $opt_with_ndbcluster && !$opt_skip_ndbcluster && $type eq 'master')
{
mtr_add_arg($args, "%s--ndbcluster", $prefix);
mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix,
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 3a65287ffc5..642a0fc13b5 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -726,27 +726,48 @@ 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'74657374311a'), (2, "'test\\_2'");
+insert into `bug20536` (`id`,`name`) values (1, _latin1 x'7465737431'), (2, "'test\\_2'");
select md5(name) from bug20536;
md5(name)
-3417d830fe24ffb2f81a28e54df2d1b3
+f4b7ce8b45a20e3c4e84bef515d1525c
48d95db0d8305c2fe11548a3635c9385
select sha1(name) from bug20536;
sha1(name)
-72228a6d56efb7a89a09543068d5d8fa4c330881
+e0b52f38deddb9f9e8d5336b153592794cb49baf
677d4d505355eb5b0549b865fcae4b7f0c28aef5
select make_set(3, name, upper(name)) from bug20536;
make_set(3, name, upper(name))
-test1,TEST1
+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
+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
+test1,TEST1,test1,TEST1,TEST1
'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2'
+CREATE TABLE t1 (
+status enum('active','passive') collate latin1_general_ci
+NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `status` enum('active','passive') character set latin1 collate latin1_general_ci NOT NULL default 'passive'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 ADD a int NOT NULL AFTER status;
+CREATE TABLE t2 (
+status enum('active','passive') collate ucs2_turkish_ci
+NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `status` enum('active','passive') character set ucs2 collate ucs2_turkish_ci NOT NULL default 'passive'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t2 ADD a int NOT NULL AFTER status;
+DROP TABLE t1,t2;
select password(name) from bug20536;
password(name)
????????????????????
@@ -755,13 +776,9 @@ select old_password(name) from bug20536;
old_password(name)
????????
????????
-select encrypt(name, 'SALT') from bug20536;
-encrypt(name, 'SALT')
-SA5pDi1UPZdys
-SA5pDi1UPZdys
select quote(name) from bug20536;
quote(name)
-??????????
+????????
????????????????
drop table bug20536;
End of 4.1 tests
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index 411cd52b4ca..cb632fcd6c8 100644
--- a/mysql-test/r/delete.result
+++ b/mysql-test/r/delete.result
@@ -172,3 +172,7 @@ a
0
2
DROP TABLE t1;
+create table t1 (a int);
+delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5;
+delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5;
+drop table t1;
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 2c79b8f8ab1..db0125b7d4f 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -559,14 +559,14 @@ COUNT(*) GROUP_CONCAT(DISTINCT t2.somename SEPARATOR ' |')
DROP TABLE t1,t2;
select * from (select group_concat('c') from DUAL) t;
group_concat('c')
-NULL
+c
create table t1 ( a int not null default 0);
select * from (select group_concat(a) from t1) t2;
group_concat(a)
NULL
select group_concat('x') UNION ALL select 1;
group_concat('x')
-NULL
+x
1
drop table t1;
CREATE TABLE t1 (id int, a varchar(9));
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 932ef133087..04f6ebe6398 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -794,7 +794,7 @@ min(7)
NULL
select min(7) from DUAL;
min(7)
-NULL
+7
explain select min(7) from t2m join t1m;
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
@@ -809,7 +809,7 @@ max(7)
NULL
select max(7) from DUAL;
max(7)
-NULL
+7
explain select max(7) from t2m join t1m;
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
@@ -848,7 +848,7 @@ min(7)
NULL
select min(7) from DUAL;
min(7)
-NULL
+7
explain select min(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
@@ -864,7 +864,7 @@ max(7)
NULL
select max(7) from DUAL;
max(7)
-NULL
+7
explain select max(7) from t2i join t1i;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2i ALL NULL NULL NULL NULL 1
@@ -942,3 +942,19 @@ EXPLAIN SELECT MAX(b) FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2
DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3);
+SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b))
+1
+1
+SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT 12))
+1
+1
+SELECT AVG(2), BIT_AND(2), BIT_OR(2), BIT_XOR(2), COUNT(*), COUNT(12),
+COUNT(DISTINCT 12), MIN(2),MAX(2),STD(2), VARIANCE(2),SUM(2),
+GROUP_CONCAT(2),GROUP_CONCAT(DISTINCT 2);
+AVG(2) BIT_AND(2) BIT_OR(2) BIT_XOR(2) COUNT(*) COUNT(12) COUNT(DISTINCT 12) MIN(2) MAX(2) STD(2) VARIANCE(2) SUM(2) GROUP_CONCAT(2) GROUP_CONCAT(DISTINCT 2)
+2.0000 2 2 2 1 1 1 2 2 0.0000 0.0000 2 2 2
+DROP TABLE t1;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 47a0f83802c..97dd8e243b2 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -646,37 +646,36 @@ drop table t1;
create table t1(f1 date, f2 time, f3 datetime);
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
-select f1 from t1 where f1 between "2006-1-1" and 20060101;
+select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date);
f1
2006-01-01
-select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
+select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date);
f1
2006-01-01
-select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
+select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date);
f1
2006-01-01
-select f2 from t1 where f2 between "12:1:2" and "12:2:2";
+select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time);
f2
12:01:02
-select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
+select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time);
f2
12:01:02
-select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
f3
2006-01-01 12:01:01
-select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
+select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
f3
2006-01-01 12:01:01
-select f1 from t1 where "2006-1-1" between f1 and f3;
+select f1 from t1 where cast("2006-1-1" as date) between f1 and f3;
f1
2006-01-01
-select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
+select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3);
f1
2006-01-01
-select f1 from t1 where "2006-1-1" between f1 and 'zzz';
+select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz';
f1
-Warnings:
-Warning 1292 Truncated incorrect date value: 'zzz'
+2006-01-01
select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
f1
2006-01-01
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index 9e674cc4aae..c41aab29853 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -63,9 +63,9 @@ Warnings:
Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c`,values(test.t1.a) AS `VALUES(a)` from test.t1
explain extended select * from t1 where values(a);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
Warnings:
-Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1
+Note 1003 select test.t1.a AS `a`,test.t1.b AS `b`,test.t1.c AS `c` from test.t1 where values(test.t1.a)
DROP TABLE t1;
create table t1(a int primary key, b int);
insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5);
@@ -197,3 +197,25 @@ PRIMARY KEY (a)
) ENGINE=MyISAM;
INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
DROP TABLE t1;
+CREATE TABLE t1
+(
+a BIGINT UNSIGNED,
+b BIGINT UNSIGNED,
+PRIMARY KEY (a)
+);
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
+IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+a b
+45 1
+INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
+IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+a b
+45 2
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
+IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+a b
+45 2
+DROP TABLE t1;
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 6a3d2bffab0..92803ec3449 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/myisam.result b/mysql-test/r/myisam.result
index ce601944f97..d7c9ba19a8a 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -773,12 +773,12 @@ show create table t1;
Table Create Table
t1 CREATE TEMPORARY TABLE `t1` (
`a` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TEST_DIR/var/log/'
show create table t1;
Table Create Table
t1 CREATE TEMPORARY TABLE `t1` (
`a` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQL_TEST_DIR/var/log/'
create table t1 (a int) engine=myisam select 42 a;
select * from t1;
a
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 6c5c757061d..721982e11e3 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -1557,4 +1557,31 @@ CREATE TABLE `t2` (
/*!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 */;
+/*!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;
+
+
+/*!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
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 01aa4ddf859..78752622db7 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -889,3 +889,50 @@ create temporary table if not exists t1 (a1 int);
execute stmt;
drop temporary table t1;
deallocate prepare stmt;
+CREATE TABLE t1(
+ID int(10) unsigned NOT NULL auto_increment,
+Member_ID varchar(15) NOT NULL default '',
+Action varchar(12) NOT NULL,
+Action_Date datetime NOT NULL,
+Track varchar(15) default NULL,
+User varchar(12) default NULL,
+Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
+CURRENT_TIMESTAMP,
+PRIMARY KEY (ID),
+KEY Action (Action),
+KEY Action_Date (Action_Date)
+);
+INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
+('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
+('111111', 'Enrolled', '2006-03-01', 'CAD' ),
+('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
+('222222', 'Enrolled', '2006-03-07', 'CAD' ),
+('222222', 'Enrolled', '2006-03-07', 'CHF' ),
+('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
+('333333', 'Enrolled', '2006-03-01', 'CAD' ),
+('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
+('444444', 'Enrolled', '2006-03-01', 'CAD' ),
+('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
+('555555', 'Enrolled', '2006-07-21', 'CAD' ),
+('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
+('666666', 'Enrolled', '2006-02-09', 'CAD' ),
+('666666', 'Enrolled', '2006-05-12', 'CHF' ),
+('666666', 'Disenrolled', '2006-06-01', 'CAD' );
+PREPARE STMT FROM
+"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
+ WHERE Member_ID=? AND Action='Enrolled' AND
+ (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
+ WHERE Member_ID=?
+ GROUP BY Track
+ HAVING Track>='CAD' AND
+ MAX(Action_Date)>'2006-03-01')";
+SET @id='111111';
+EXECUTE STMT USING @id,@id;
+GROUP_CONCAT(Track SEPARATOR ', ')
+NULL
+SET @id='222222';
+EXECUTE STMT USING @id,@id;
+GROUP_CONCAT(Track SEPARATOR ', ')
+CAD
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index f5abc4ed42a..ba4de7f6406 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1001,7 +1001,7 @@ INSERT INTO t1 VALUES (1);
UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
select * from t1;
i
-1
+2
drop table t1;
CREATE TABLE t1 (a int(1));
EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
@@ -1193,7 +1193,7 @@ UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
ERROR 42S02: Unknown table 't' in field list
select * from t1;
i
-1
+3
drop table t1;
CREATE TABLE t1 (
id int(11) default NULL
@@ -2917,3 +2917,32 @@ retailerID statusID changed
0048 1 2006-01-06 12:37:50
0059 1 2006-01-06 12:37:50
drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 38 NULL 2 Using where
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+2 DEPENDENT SUBQUERY t2 range b b 38 NULL 2 Using where
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index 3428b5969d9..99e9adf84ca 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -27,12 +27,12 @@ INSERT INTO t1 VALUES ( "2000-1-2" );
INSERT INTO t1 VALUES ( "2000-1-3" );
INSERT INTO t1 VALUES ( "2000-1-4" );
INSERT INTO t1 VALUES ( "2000-1-5" );
-SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
+SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date);
datum
2000-01-02
2000-01-03
2000-01-04
-SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
+SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY;
datum
DROP TABLE t1;
CREATE TABLE t1 (
@@ -104,3 +104,9 @@ SELECT * FROM t1;
y
0000
DROP TABLE t1;
+create table t1(start_date date, end_date date);
+insert into t1 values ('2000-01-01','2000-01-02');
+select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date;
+1
+1
+drop table t1;
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index 0ad38d98403..641080f48ab 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -475,13 +475,34 @@ 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'74657374311a'), (2, "'test\\_2'");
+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;
+#
+# Bug #20108: corrupted default enum value for a ucs2 field
+#
+
+CREATE TABLE t1 (
+ status enum('active','passive') collate latin1_general_ci
+ NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ADD a int NOT NULL AFTER status;
+
+CREATE TABLE t2 (
+ status enum('active','passive') collate ucs2_turkish_ci
+ NOT NULL default 'passive'
+);
+SHOW CREATE TABLE t2;
+ALTER TABLE t2 ADD a int NOT NULL AFTER status;
+
+DROP TABLE t1,t2;
+
+
# 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
@@ -489,12 +510,6 @@ select export_set(5, name, upper(name), ",", 5) from bug20536;
select password(name) from bug20536;
select old_password(name) from bug20536;
-# 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;
-
# 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.
diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test
index 98e4c4e35fa..d4eb01cab23 100644
--- a/mysql-test/t/delete.test
+++ b/mysql-test/t/delete.test
@@ -153,4 +153,14 @@ DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1;
SELECT * FROM t1;
DROP TABLE t1;
+#
+# Bug #21392: multi-table delete with alias table name fails with
+# 1003: Incorrect table name
+#
+
+create table t1 (a int);
+delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5;
+delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5;
+drop table t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index f8a3ed0f25e..18cb5d0a430 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -617,4 +617,18 @@ SELECT MAX(b) FROM t1;
EXPLAIN SELECT MAX(b) FROM t1;
DROP TABLE t1;
+#
+# Bug #16792 query with subselect, join, and group not returning proper values
+#
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3);
+
+SELECT (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+SELECT (SELECT COUNT(DISTINCT 12)) FROM t1 GROUP BY t1.a;
+# an attempt to test all aggregate function with no table.
+SELECT AVG(2), BIT_AND(2), BIT_OR(2), BIT_XOR(2), COUNT(*), COUNT(12),
+ COUNT(DISTINCT 12), MIN(2),MAX(2),STD(2), VARIANCE(2),SUM(2),
+ GROUP_CONCAT(2),GROUP_CONCAT(DISTINCT 2);
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 472f3d81d2b..04bfc741d1c 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -341,20 +341,20 @@ drop table t1;
#
# Bug#16377 result of DATE/TIME functions were compared as strings which
# can lead to a wrong result.
-#
+# Now wrong dates should be compared only with CAST()
create table t1(f1 date, f2 time, f3 datetime);
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
-select f1 from t1 where f1 between "2006-1-1" and 20060101;
-select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
-select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
-select f2 from t1 where f2 between "12:1:2" and "12:2:2";
-select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
-select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
-select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
-select f1 from t1 where "2006-1-1" between f1 and f3;
-select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
-select f1 from t1 where "2006-1-1" between f1 and 'zzz';
+select f1 from t1 where f1 between CAST("2006-1-1" as date) and CAST(20060101 as date);
+select f1 from t1 where f1 between cast("2006-1-1" as date) and cast("2006.1.1" as date);
+select f1 from t1 where date(f1) between cast("2006-1-1" as date) and cast("2006.1.1" as date);
+select f2 from t1 where f2 between cast("12:1:2" as time) and cast("12:2:2" as time);
+select f2 from t1 where time(f2) between cast("12:1:2" as time) and cast("12:2:2" as time);
+select f3 from t1 where f3 between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
+select f3 from t1 where timestamp(f3) between cast("2006-1-1 12:1:1" as datetime) and cast("2006-1-1 12:1:2" as datetime);
+select f1 from t1 where cast("2006-1-1" as date) between f1 and f3;
+select f1 from t1 where cast("2006-1-1" as date) between date(f1) and date(f3);
+select f1 from t1 where cast("2006-1-1" as date) between f1 and 'zzz';
select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
drop table t1;
diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test
index 8038bd7bfe7..56885a555fd 100644
--- a/mysql-test/t/insert_update.test
+++ b/mysql-test/t/insert_update.test
@@ -115,4 +115,27 @@ INSERT INTO t1 ( a ) SELECT 0 ON DUPLICATE KEY UPDATE a = a + VALUES (a) ;
DROP TABLE t1;
+#
+# Bug#21555: incorrect behavior with INSERT ... ON DUPL KEY UPDATE and VALUES
+#
+
+
# End of 4.1 tests
+CREATE TABLE t1
+(
+ a BIGINT UNSIGNED,
+ b BIGINT UNSIGNED,
+ PRIMARY KEY (a)
+);
+
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
+ IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+INSERT INTO t1 VALUES (45, 2) ON DUPLICATE KEY UPDATE b =
+ IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+INSERT INTO t1 VALUES (45, 1) ON DUPLICATE KEY UPDATE b =
+ IF(VALUES(b) > t1.b, VALUES(b), t1.b);
+SELECT * FROM t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index ef9f63067a4..f70cf835588 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/myisam.test b/mysql-test/t/myisam.test
index be7bec117f3..11d0693b511 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -734,14 +734,20 @@ connect (session2,localhost,root,,);
connection session1;
disable_query_log;
-eval create temporary table t1 (a int) engine=myisam data directory="$MYSQL_TEST_DIR/var/tmp" select 9 a;
+eval create temporary table t1 (a int) engine=myisam data directory="$MYSQL_TEST_DIR/var/log" select 9 a;
enable_query_log;
+# If running test suite with a non standard tmp dir, the "show create table"
+# will print "DATA_DIRECTORY=". Use replace_result to mask it out
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
show create table t1;
connection session2;
disable_query_log;
-eval create temporary table t1 (a int) engine=myisam data directory="$MYSQL_TEST_DIR/var/tmp" select 99 a;
+eval create temporary table t1 (a int) engine=myisam data directory="$MYSQL_TEST_DIR/var/log" select 99 a;
enable_query_log;
+# If running test suite with a non standard tmp dir, the "show create table"
+# will print "DATA_DIRECTORY=". Use replace_result to mask it out
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
show create table t1;
connection default;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index e86635e24d0..b0df2bb9db2 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -694,4 +694,12 @@ create table t3(a int);
--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
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 0ca293eb1ba..7c2a42404ad 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -951,4 +951,56 @@ execute stmt;
drop temporary table t1;
deallocate prepare stmt;
+#
+# BUG#22085: Crash on the execution of a prepared statement that
+# uses an IN subquery with aggregate functions in HAVING
+#
+
+CREATE TABLE t1(
+ ID int(10) unsigned NOT NULL auto_increment,
+ Member_ID varchar(15) NOT NULL default '',
+ Action varchar(12) NOT NULL,
+ Action_Date datetime NOT NULL,
+ Track varchar(15) default NULL,
+ User varchar(12) default NULL,
+ Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update
+ CURRENT_TIMESTAMP,
+ PRIMARY KEY (ID),
+ KEY Action (Action),
+ KEY Action_Date (Action_Date)
+);
+
+INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES
+ ('111111', 'Disenrolled', '2006-03-01', 'CAD' ),
+ ('111111', 'Enrolled', '2006-03-01', 'CAD' ),
+ ('111111', 'Disenrolled', '2006-07-03', 'CAD' ),
+ ('222222', 'Enrolled', '2006-03-07', 'CAD' ),
+ ('222222', 'Enrolled', '2006-03-07', 'CHF' ),
+ ('222222', 'Disenrolled', '2006-08-02', 'CHF' ),
+ ('333333', 'Enrolled', '2006-03-01', 'CAD' ),
+ ('333333', 'Disenrolled', '2006-03-01', 'CAD' ),
+ ('444444', 'Enrolled', '2006-03-01', 'CAD' ),
+ ('555555', 'Disenrolled', '2006-03-01', 'CAD' ),
+ ('555555', 'Enrolled', '2006-07-21', 'CAD' ),
+ ('555555', 'Disenrolled', '2006-03-01', 'CHF' ),
+ ('666666', 'Enrolled', '2006-02-09', 'CAD' ),
+ ('666666', 'Enrolled', '2006-05-12', 'CHF' ),
+ ('666666', 'Disenrolled', '2006-06-01', 'CAD' );
+
+PREPARE STMT FROM
+"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1
+ WHERE Member_ID=? AND Action='Enrolled' AND
+ (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1
+ WHERE Member_ID=?
+ GROUP BY Track
+ HAVING Track>='CAD' AND
+ MAX(Action_Date)>'2006-03-01')";
+SET @id='111111';
+EXECUTE STMT USING @id,@id;
+SET @id='222222';
+EXECUTE STMT USING @id,@id;
+
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 10dfb788c10..1018b5de005 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1885,4 +1885,30 @@ select * from t1 r1
group by r2.retailerId);
drop table t1;
+#
+# Bug #21180: Subselect with index for both WHERE and ORDER BY
+# produces empty result
+#
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+
+drop table t1,t2;
+
# End of 4.1 tests
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index 78bdd9b8a80..c6050753943 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -36,8 +36,8 @@ INSERT INTO t1 VALUES ( "2000-1-2" );
INSERT INTO t1 VALUES ( "2000-1-3" );
INSERT INTO t1 VALUES ( "2000-1-4" );
INSERT INTO t1 VALUES ( "2000-1-5" );
-SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4";
-SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY;
+SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND cast("2000-1-4" as date);
+SELECT * FROM t1 WHERE datum BETWEEN cast("2000-1-2" as date) AND datum - INTERVAL 100 DAY;
DROP TABLE t1;
#
@@ -115,4 +115,11 @@ INSERT INTO t1 VALUES ('abc');
SELECT * FROM t1;
DROP TABLE t1;
+#
+# Bug#21677: Wrong result when comparing a DATE and a DATETIME in BETWEEN
+#
+create table t1(start_date date, end_date date);
+insert into t1 values ('2000-01-01','2000-01-02');
+select 1 from t1 where cast('2000-01-01 12:01:01' as datetime) between start_date and end_date;
+drop table t1;
# End of 4.1 tests
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index cf26428d65f..efc19927183 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -44,7 +44,9 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
DBUG_PRINT("my",("fd: %d length: %lu MyFlags: %d",fd,(ulong) newlength,
MyFlags));
- oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
+ if ((oldsize = my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE))) == newlength)
+ DBUG_RETURN(0);
+
DBUG_PRINT("info",("old_size: %ld", (ulong) oldsize));
if (oldsize > newlength)
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/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp
index 46e44226e18..5498b21a962 100644
--- a/ndb/include/ndbapi/NdbOperation.hpp
+++ b/ndb/include/ndbapi/NdbOperation.hpp
@@ -445,7 +445,7 @@ public:
/**
* Interpreted program instruction:
- * Substract RegSource1 from RegSource2 and put the result in RegDest.
+ * Substract RegSource2 from RegSource1 and put the result in RegDest.
*
* @param RegSource1 First register.
* @param RegSource2 Second register.
diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt
index de32ce91ee8..d6dfcfe8587 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 6006
Next DBDIH 7174
-Next DBTC 8037
+Next DBTC 8038
Next CMVMI 9000
Next BACKUP 10022
Next DBUTIL 11002
@@ -281,6 +281,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/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 65c864bd853..02ec5782c3e 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -8338,6 +8338,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 42e38b41b4b..bc6671f805d 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -6435,6 +6435,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;
@@ -12508,6 +12509,20 @@ void Dblqh::lastWriteInFileLab(Signal* signal)
void Dblqh::writePageZeroLab(Signal* signal)
{
+ if (logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM)
+ {
+ if (logPartPtr.p->firstLogQueue == RNIL)
+ {
+ jam();
+ logPartPtr.p->logPartState = LogPartRecord::IDLE;
+ }
+ else
+ {
+ jam();
+ logPartPtr.p->logPartState = LogPartRecord::ACTIVE;
+ }
+ }
+
logFilePtr.p->fileChangeState = LogFileRecord::NOT_ONGOING;
/*---------------------------------------------------------------------------*/
/* IT COULD HAVE ARRIVED PAGE WRITES TO THE CURRENT FILE WHILE WE WERE */
diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
index 25c746b0a89..4488e7500f5 100644
--- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -718,7 +718,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
@@ -806,7 +806,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 a71942f5cc8..ab0981a98ef 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -1757,8 +1757,7 @@ void Dbtc::execKEYINFO(Signal* signal)
apiConnectptr.i = signal->theData[0];
tmaxData = 20;
if (apiConnectptr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal);
+ TCKEY_abort(signal, 18);
return;
}//if
ptrAss(apiConnectptr, apiConnectRecord);
@@ -1767,9 +1766,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) {
@@ -2467,7 +2464,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;
@@ -3210,7 +3207,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;
@@ -8551,6 +8548,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;
}
@@ -11915,14 +11913,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.indexSchemaVersion;
+ }
+
Uint32 remainingKey = indexOp->keyInfo.getSize();
bool moreKeyData = indexOp->keyInfo.first(keyIter);
// *********** KEYINFO in TCKEYREQ ***********
@@ -11941,21 +11943,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();
@@ -11975,6 +11969,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;
}
@@ -11985,10 +11983,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;
}
/**
@@ -12039,7 +12059,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
@@ -12112,9 +12132,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();
@@ -12135,6 +12162,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;
}
@@ -12145,6 +12179,12 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
}
}
@@ -12174,6 +12214,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;
}
@@ -12573,9 +12620,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) {
@@ -12605,6 +12659,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;
}
@@ -12640,6 +12700,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;
}
@@ -12657,6 +12724,11 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
}
}
@@ -12692,6 +12764,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;
}
@@ -12728,6 +12806,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;
}
@@ -12873,9 +12957,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) {
@@ -12906,6 +12997,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;
}
@@ -12942,6 +13039,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 8171fa65771..a1f8b827752 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -1111,14 +1111,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/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index 5a841d6f836..f6970ecce2d 100644
--- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -177,13 +177,12 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal)
"the state of a fragment scan was out of sync.",
killingNode);
break;
-
+
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:
@@ -2037,6 +2036,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);
@@ -2827,7 +2831,7 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
}
}
-
+
signal->theData[0] = EventReport::NDBStartCompleted;
signal->theData[1] = NDB_VERSION;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 0a39651ce28..469231512f5 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -504,6 +504,8 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend)
idx = m_current_api_receiver;
last = m_api_receivers_count;
+
+ Uint32 timeout = tp->m_waitfor_timeout;
do {
if(theError.code){
@@ -531,7 +533,7 @@ int NdbScanOperation::nextResult(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 {
@@ -1372,6 +1374,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;
@@ -1379,7 +1382,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;
}
@@ -1520,6 +1523,8 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){
return -1;
}
+ Uint32 timeout = tp->m_waitfor_timeout;
+
/**
* Wait for outstanding
*/
@@ -1527,7 +1532,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;
@@ -1597,7 +1602,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/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp
index d359f83257f..174f6f170f4 100644
--- a/ndb/test/ndbapi/testIndex.cpp
+++ b/ndb/test/ndbapi/testIndex.cpp
@@ -1201,6 +1201,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"
@@ -1507,6 +1549,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 e9064d6e30b..39782ecbbc7 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -474,6 +474,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/sql/field.h b/sql/field.h
index a33cb0a93aa..79fb7ff76d1 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1192,6 +1192,8 @@ public:
uint decimals,flags,pack_length;
Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
+ TYPELIB *save_interval; // Temporary copy for the above
+ // Used only for UCS2 intervals
List<String> interval_list;
CHARSET_INFO *charset;
Field::geometry_type geom_type;
diff --git a/sql/item.h b/sql/item.h
index 3eab695cb5e..ad8bea663f1 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1241,7 +1241,11 @@ public:
{
return Item_field::save_in_field(field_arg, no_conversions);
}
- table_map used_tables() const { return (table_map)0L; }
+ /*
+ We use RAND_TABLE_BIT to prevent Item_insert_value from
+ being treated as a constant and precalculated before execution
+ */
+ table_map used_tables() const { return RAND_TABLE_BIT; }
bool walk(Item_processor processor, byte *args)
{
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index a32bd0a7337..6b6996160a1 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -75,119 +75,14 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
This function aggregates result types from the array of items. Found type
supposed to be used later for comparison of values of these items.
Aggregation itself is performed by the item_cmp_type() function.
-
- NOTES
- Aggregation rules:
- If there are DATE/TIME fields/functions in the list and no string
- fields/functions in the list then:
- The INT_RESULT type will be used for aggregation instead of original
- result type of any DATE/TIME field/function in the list
- All constant items in the list will be converted to a DATE/TIME using
- found field or result field of found function.
-
- Implementation notes:
- The code is equivalent to:
- 1. Check the list for presence of a STRING field/function.
- Collect the is_const flag.
- 2. Get a Field* object to use for type coercion
- 3. Perform type conversion.
- 1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME
- field/function and checks presence of a STRING field/function.
- The second loop works only if a DATE/TIME field/function is found.
- It checks presence of a STRING field/function in the rest of the list.
-
- TODO
- 1) The current implementation can produce false comparison results for
- expressions like:
- date_time_field BETWEEN string_field_with_dates AND string_constant
- if the string_constant will omit some of leading zeroes.
- In order to fully implement correct comparison of DATE/TIME the new
- DATETIME_RESULT result type should be introduced and agg_cmp_type()
- should return the DATE/TIME field used for the conversion. Later
- this field can be used by comparison functions like Item_func_between to
- convert string values to ints on the fly and thus return correct results.
- This modification will affect functions BETWEEN, IN and CASE.
-
- 2) If in the list a DATE field/function and a DATETIME field/function
- are present in the list then the first found field/function will be
- used for conversion. This may lead to wrong results and probably should
- be fixed.
*/
static void agg_cmp_type(THD *thd, Item_result *type, Item **items, uint nitems)
{
uint i;
- Item::Type res= (Item::Type)0;
- /* Used only for date/time fields, max_length = 19 */
- char buff[20];
- uchar null_byte;
- Field *field= NULL;
-
- /* Search for date/time fields/functions */
- for (i= 0; i < nitems; i++)
- {
- 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)
- {
- 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)
- {
- /* Check the rest of the list for presence of a string field/function. */
- for (i++ ; i < nitems; i++)
- {
- if (!items[i]->const_item() && items[i]->result_type() == STRING_RESULT &&
- !items[i]->result_as_longlong())
- {
- if (res == Item::FUNC_ITEM)
- delete field;
- field= 0;
- break;
- }
- }
- }
- /*
- If the first item is a date/time function then its result should be
- compared as int
- */
- if (field)
- /* Suppose we are comparing dates */
- type[0]= INT_RESULT;
- else
- type[0]= items[0]->result_type();
-
- for (i= 0; i < nitems ; i++)
- {
- Item_result result= items[i]->result_type();
- if (field &&
- ((!items[i]->const_item() && items[i]->result_as_longlong()) ||
- (items[i]->const_item() && convert_constant_item(thd, field,
- &items[i]))))
- result= INT_RESULT;
- type[0]= item_cmp_type(type[0], result);
- }
-
- if (res == Item::FUNC_ITEM && field)
- delete field;
+ type[0]= items[0]->result_type();
+ for (i= 1 ; i < nitems ; i++)
+ type[0]= item_cmp_type(type[0], items[i]->result_type());
}
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
@@ -1021,8 +916,30 @@ void Item_func_between::fix_length_and_dec()
if (!args[0] || !args[1] || !args[2])
return;
agg_cmp_type(thd, &cmp_type, args, 3);
- if (cmp_type == STRING_RESULT)
- agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV);
+ if (cmp_type == STRING_RESULT &&
+ agg_arg_charsets(cmp_collation, args, 3, MY_COLL_CMP_CONV))
+ return;
+
+ /*
+ Make a special case of compare with date/time and longlong fields.
+ They are compared as integers, so for const item this time-consuming
+ conversion can be done only once, not for every single comparison
+ */
+ if (args[0]->type() == FIELD_ITEM)
+ {
+ Field *field=((Item_field*) args[0])->field;
+ if (field->can_be_compared_as_longlong())
+ {
+ /*
+ The following can't be recoded with || as convert_constant_item
+ changes the argument
+ */
+ if (convert_constant_item(thd, field,&args[1]))
+ cmp_type=INT_RESULT; // Works for all types.
+ if (convert_constant_item(thd, field,&args[2]))
+ cmp_type=INT_RESULT; // Works for all types.
+ }
+ }
}
diff --git a/sql/log.cc b/sql/log.cc
index 78605de3141..7e97bfd0712 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -409,13 +409,18 @@ shutdown the MySQL server and restart it.", log_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
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 9c5bcc2d53f..4a5658c5ccf 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -305,6 +305,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
#define TL_OPTION_UPDATING 1
#define TL_OPTION_FORCE_INDEX 2
#define TL_OPTION_IGNORE_LEAVES 4
+#define TL_OPTION_ALIAS 8
/* Some portable defines */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 57903ffe7b9..85125a4521a 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2980,6 +2980,14 @@ int QUICK_SELECT::get_next()
}
}
+void QUICK_SELECT::reset(void)
+{
+ next= 0;
+ it.rewind();
+ range= 0;
+ if (file->inited == handler::NONE)
+ file->ha_index_init(index);
+}
/* Get next for geometrical indexes */
@@ -3201,7 +3209,11 @@ bool QUICK_SELECT_DESC::test_if_null_range(QUICK_RANGE *range_arg,
return 0;
}
#endif
-
+void QUICK_SELECT_DESC::reset(void)
+{
+ rev_it.rewind();
+ QUICK_SELECT::reset();
+}
/*****************************************************************************
** Print a quick range for debugging
diff --git a/sql/opt_range.h b/sql/opt_range.h
index d2f4452a762..367a85dc6f2 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -86,7 +86,7 @@ public:
QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0);
virtual ~QUICK_SELECT();
- void reset(void) { next=0; it.rewind(); range= NULL;}
+ virtual void reset(void);
int init()
{
key_part_info= head->key_info[index].key_part;
@@ -120,7 +120,7 @@ private:
#ifdef NOT_USED
bool test_if_null_range(QUICK_RANGE *range, uint used_key_parts);
#endif
- void reset(void) { next=0; rev_it.rewind(); }
+ void reset(void);
List<QUICK_RANGE> rev_ranges;
List_iterator<QUICK_RANGE> rev_it;
};
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index b53fbfd3f80..bc98c96b5a8 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -182,7 +182,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
Type of range for the key part for this field will be
returned in range_fl.
*/
- if ((outer_tables & table->map) ||
+ if (table->file->inited || (outer_tables & table->map) ||
!find_key_for_maxmin(0, &ref, item_field->field, conds,
&range_fl, &prefix_len))
{
@@ -269,7 +269,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
Type of range for the key part for this field will be
returned in range_fl.
*/
- if ((outer_tables & table->map) ||
+ if (table->file->inited || (outer_tables & table->map) ||
!find_key_for_maxmin(1, &ref, item_field->field, conds,
&range_fl, &prefix_len))
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e8fe175cd7c..a995a492bc8 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -177,6 +177,7 @@ public:
bool need_mutex);
int find_next_log(LOG_INFO* linfo, bool need_mutex);
int get_current_log(LOG_INFO* linfo);
+ int raw_get_current_log(LOG_INFO* linfo);
uint next_file_id();
inline bool is_open() { return log_type != LOG_CLOSED; }
inline char* get_index_fname() { return index_file_name;}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 89ecceeb1bf..59c4026ba7f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4863,6 +4863,7 @@ bool add_to_list(THD *thd, SQL_LIST &list,Item *item,bool asc)
table_options A set of the following bits:
TL_OPTION_UPDATING Table will be updated
TL_OPTION_FORCE_INDEX Force usage of index
+ TL_OPTION_ALIAS an alias in multi table DELETE
lock_type How table should be locked
use_index List of indexed used in USE INDEX
ignore_index List of indexed used in IGNORE INDEX
@@ -4888,7 +4889,8 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
if (!table)
DBUG_RETURN(0); // End of memory
alias_str= alias ? alias->str : table->table.str;
- if (check_table_name(table->table.str,table->table.length) ||
+ if (!test(table_options & TL_OPTION_ALIAS) &&
+ check_table_name(table->table.str,table->table.length) ||
table->db.str && check_db_name(table->db.str))
{
net_printf(thd, ER_WRONG_TABLE_NAME, table->table.str);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 963c4ccf5a6..2a7ab55b8c4 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1359,10 +1359,14 @@ int show_binlogs(THD* thd)
MYSQL_TYPE_LONGLONG));
if (protocol->send_fields(&field_list, 1))
DBUG_RETURN(1);
+
+ 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_select.cc b/sql/sql_select.cc
index bb0895b3117..62eb5235d70 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -290,8 +290,6 @@ JOIN::prepare(Item ***rref_pointer_array,
select_lex->having_fix_field= 0;
if (having_fix_rc || thd->net.report_error)
DBUG_RETURN(-1); /* purecov: inspected */
- if (having->with_sum_func)
- having->split_sum_func2(thd, ref_pointer_array, all_fields, &having);
}
// Is it subselect
@@ -306,6 +304,9 @@ JOIN::prepare(Item ***rref_pointer_array,
}
}
+ if (having && having->with_sum_func)
+ having->split_sum_func2(thd, ref_pointer_array, all_fields, &having);
+
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
DBUG_RETURN(-1);
@@ -1131,7 +1132,7 @@ JOIN::exec()
DBUG_VOID_RETURN;
}
- if (!tables_list)
+ if (!tables_list && (tables || !select_lex->with_sum_func))
{ // Only test of functions
if (select_options & SELECT_DESCRIBE)
select_describe(this, FALSE, FALSE, FALSE,
@@ -1170,7 +1171,12 @@ JOIN::exec()
thd->examined_row_count= 0;
DBUG_VOID_RETURN;
}
- thd->limit_found_rows= thd->examined_row_count= 0;
+ /*
+ don't reset the found rows count if there're no tables
+ as FOUND_ROWS() may be called.
+ */
+ if (tables)
+ thd->limit_found_rows= thd->examined_row_count= 0;
if (zero_result_cause)
{
@@ -1209,7 +1215,8 @@ JOIN::exec()
having= tmp_having;
select_describe(this, need_tmp,
order != 0 && !skip_sort_order,
- select_distinct);
+ select_distinct,
+ !tables ? "No tables used" : NullS);
DBUG_VOID_RETURN;
}
@@ -5576,10 +5583,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->key_length=0;
keyinfo->rec_per_key=0;
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
- for (; group ; group=group->next,key_part_info++)
+ ORDER *cur_group= group;
+ for (; cur_group ; cur_group= cur_group->next, key_part_info++)
{
- Field *field=(*group->item)->get_tmp_table_field();
- bool maybe_null=(*group->item)->maybe_null;
+ Field *field=(*cur_group->item)->get_tmp_table_field();
+ bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
key_part_info->offset= field->offset();
@@ -5591,8 +5599,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
0 : FIELDFLAG_BINARY;
if (!using_unique_constraint)
{
- group->buff=(char*) group_buff;
- if (!(group->field=field->new_field(thd->mem_root,table)))
+ cur_group->buff=(char*) group_buff;
+ if (!(cur_group->field=field->new_field(thd->mem_root,table)))
goto err; /* purecov: inspected */
if (maybe_null)
{
@@ -5606,21 +5614,16 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->null_bit=field->null_bit;
key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) table->record[0]);
- group->field->move_field((char*) ++group->buff);
+ cur_group->field->move_field((char*) ++cur_group->buff);
group_buff++;
}
else
- group->field->move_field((char*) group_buff);
+ cur_group->field->move_field((char*) group_buff);
group_buff+= key_part_info->length;
}
keyinfo->key_length+= key_part_info->length;
}
}
- else
- {
- set_if_smaller(table->max_rows, rows_limit);
- param->end_write_records= rows_limit;
- }
if (distinct && field_count != param->hidden_field_count)
{
@@ -5683,6 +5686,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->max_rows, rows_limit);
+ param->end_write_records= rows_limit;
+ }
+
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
table->db_record_offset=1;
@@ -6032,9 +6049,12 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
else
end_select=end_send;
}
- join->join_tab[join->tables-1].next_select=end_select;
+ if (join->tables)
+ {
+ join->join_tab[join->tables-1].next_select=end_select;
- join_tab=join->join_tab+join->const_tables;
+ join_tab=join->join_tab+join->const_tables;
+ }
join->send_records=0;
if (join->tables == join->const_tables)
{
@@ -6052,6 +6072,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
}
else
{
+ DBUG_ASSERT(join_tab);
error= sub_select(join,join_tab,0);
if (error >= 0)
error= sub_select(join,join_tab,1);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index efd83549312..73fab642264 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4345,14 +4345,17 @@ table_wild_one:
ident opt_wild opt_table_alias
{
if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
- TL_OPTION_UPDATING, Lex->lock_option))
+ TL_OPTION_UPDATING |
+ TL_OPTION_ALIAS, Lex->lock_option))
YYABORT;
}
| ident '.' ident opt_wild opt_table_alias
{
if (!Select->add_table_to_list(YYTHD,
new Table_ident(YYTHD, $1, $3, 0),
- $5, TL_OPTION_UPDATING,
+ $5,
+ TL_OPTION_UPDATING |
+ TL_OPTION_ALIAS,
Lex->lock_option))
YYABORT;
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index e3bf763f700..e4fdc77912c 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -190,13 +190,19 @@ bool mysql_create_frm(THD *thd, my_string file_name,
goto err3;
{
- /* Unescape all UCS2 intervals: were escaped in pack_headers */
+ /*
+ Restore all UCS2 intervals.
+ HEX representation of them is not needed anymore.
+ */
List_iterator<create_field> it(create_fields);
create_field *field;
while ((field=it++))
{
- if (field->interval && field->charset->mbminlen > 1)
- unhex_type2(field->interval);
+ if (field->save_interval)
+ {
+ field->interval= field->save_interval;
+ field->save_interval= 0;
+ }
}
}
DBUG_RETURN(0);
@@ -452,18 +458,36 @@ static bool pack_header(uchar *forminfo, enum db_type table_type,
reclength=(uint) (field->offset+ data_offset + length);
n_length+= (ulong) strlen(field->field_name)+1;
field->interval_id=0;
+ field->save_interval= 0;
if (field->interval)
{
uint old_int_count=int_count;
if (field->charset->mbminlen > 1)
{
- /* Escape UCS2 intervals using HEX notation */
+ /*
+ Escape UCS2 intervals using HEX notation to avoid
+ problems with delimiters between enum elements.
+ As the original representation is still needed in
+ the function make_empty_rec to create a record of
+ filled with default values it is saved in save_interval
+ The HEX representation is created from this copy.
+ */
+ field->save_interval= field->interval;
+ field->interval= (TYPELIB*) sql_alloc(sizeof(TYPELIB));
+ *field->interval= *field->save_interval;
+ field->interval->type_names=
+ (const char **) sql_alloc(sizeof(char*) *
+ (field->interval->count+1));
+ field->interval->type_names[field->interval->count]= 0;
+ field->interval->type_lengths=
+ (uint *) sql_alloc(sizeof(uint) * field->interval->count);
+
for (uint pos= 0; pos < field->interval->count; pos++)
{
char *dst;
- uint length= field->interval->type_lengths[pos], hex_length;
- const char *src= field->interval->type_names[pos];
+ uint length= field->save_interval->type_lengths[pos], hex_length;
+ const char *src= field->save_interval->type_names[pos];
const char *srcend= src + length;
hex_length= length * 2;
field->interval->type_lengths[pos]= hex_length;
@@ -715,7 +739,8 @@ static bool make_empty_rec(File file,enum db_type table_type,
field->charset,
field->geom_type,
field->unireg_check,
- field->interval,
+ field->save_interval ? field->save_interval :
+ field->interval,
field->field_name,
&table);
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 9cead3fce3f..1daac2d0e95 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -649,6 +649,8 @@ 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_size.pl
+%attr(-, root, root) %{_datadir}/mysql/ndb_size.tmpl
%files ndb-extra
%defattr(-,root,root,0755)
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 7a87fc78ea5..9fabde993b8 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -9952,8 +9952,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;