summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.ndb.mysql.com>2005-06-04 19:26:35 +0200
committerunknown <tomas@poseidon.ndb.mysql.com>2005-06-04 19:26:35 +0200
commit84f89641cfc6acff016b973c3bfa12ef0a31fe12 (patch)
tree5a32b384f0388487fb7fee12035b2f2e36fb75d9
parent7b3cd08e9bb71e57102a5aa5ab2237980bf92b02 (diff)
parentdab1b26b1d3ec57e11681459282de2fe81e362f3 (diff)
downloadmariadb-git-84f89641cfc6acff016b973c3bfa12ef0a31fe12.tar.gz
Merge
BitKeeper/etc/logging_ok: auto-union libmysqld/Makefile.am: Auto merged sql/field.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/ha_ndbcluster.h: Auto merged sql/item.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_yacc.yy: Auto merged storage/ndb/src/mgmclient/CommandInterpreter.cpp: Auto merged sql/sql_bitmap.h: merge
-rw-r--r--BUILD/Makefile.am1
-rwxr-xr-xBUILD/check-cpu168
-rw-r--r--BitKeeper/etc/logging_ok2
-rw-r--r--VC++Files/client/mysql.dsp8
-rw-r--r--VC++Files/client/mysqladmin.dsp6
-rw-r--r--VC++Files/client/mysqlimport.dsp8
-rw-r--r--VC++Files/client/mysqlshow.dsp8
-rw-r--r--VC++Files/libmysql/libmysql.dsp4
-rw-r--r--VC++Files/mysql.dsw12
-rw-r--r--client/mysql.cc95
-rw-r--r--config/ac-macros/yassl.m44
-rw-r--r--extra/yassl/src/ssl.cpp2
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp5
-rw-r--r--extra/yassl/taocrypt/src/template_instnt.cpp20
-rw-r--r--include/config-win.h1
-rw-r--r--include/mysql.h4
-rw-r--r--libmysql/libmysql.c7
-rw-r--r--libmysqld/Makefile.am27
-rw-r--r--mysql-test/r/case.result17
-rw-r--r--mysql-test/r/ctype_utf8.result3
-rw-r--r--mysql-test/r/func_if.result17
-rw-r--r--mysql-test/r/func_time.result3
-rw-r--r--mysql-test/r/ndb_condition_pushdown.result627
-rw-r--r--mysql-test/r/variables.result6
-rw-r--r--mysql-test/t/case.test19
-rw-r--r--mysql-test/t/ctype_utf8.test7
-rw-r--r--mysql-test/t/func_if.test14
-rw-r--r--mysql-test/t/func_time.test6
-rw-r--r--mysql-test/t/ndb_condition_pushdown.test594
-rw-r--r--mysql-test/t/variables.test7
-rw-r--r--mysys/mf_keycache.c121
-rw-r--r--sql/field.cc15
-rw-r--r--sql/ha_innodb.cc22
-rw-r--r--sql/ha_ndbcluster.cc1229
-rw-r--r--sql/ha_ndbcluster.h36
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item.h8
-rw-r--r--sql/item_cmpfunc.cc33
-rw-r--r--sql/item_cmpfunc.h30
-rw-r--r--sql/item_func.cc47
-rw-r--r--sql/item_func.h10
-rw-r--r--sql/item_subselect.cc2
-rw-r--r--sql/item_timefunc.cc7
-rw-r--r--sql/set_var.cc3
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_bitmap.h24
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_yacc.yy6
-rw-r--r--tests/mysql_client_test.c16
52 files changed, 2607 insertions, 730 deletions
diff --git a/BUILD/Makefile.am b/BUILD/Makefile.am
index d60672e05f8..27a42cdca16 100644
--- a/BUILD/Makefile.am
+++ b/BUILD/Makefile.am
@@ -19,6 +19,7 @@
EXTRA_DIST = FINISH.sh \
SETUP.sh \
+ check-cpu \
compile-alpha \
compile-alpha-ccc \
compile-alpha-cxx \
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index 0283c669fb2..3ceb9c269fe 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -6,113 +6,197 @@
#
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 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
+
+ # 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)
+ FreeBSD|OpenBSD)
cpu_family=`uname -m`;
- model_name=`sysctl -b hw.model`
+ model_name=`sysctl -n hw.model`
+ ;;
+ Darwin)
+ cpu_family=`uname -p`
+ model_name=`machine`
;;
*)
cpu_family=`uname -m`;
- model_name="unknown";
+ model_name=`uname -p`;
;;
esac
fi
-cpu_flag=""
-cpu_flag_old=""
+# 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_flag="ev6";
+ cpu_arg="ev6";
;;
+
+ # Intel ia32
*Xeon*)
- cpu_flag="nocona";
+ # 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
;;
- *Pentium*4*Mobile*CPU*)
- cpu_flag="pentium4m";
+ *Pentium*4*Mobile*)
+ cpu_arg="pentium4m";
;;
- *Pentium*4*CPU*)
- cpu_flag="pentium4";
+ *Pentium*4*)
+ cpu_arg="pentium4";
;;
- *Pentium*III*Mobile*CPU*)
- cpu_flag="pentium3m";
+ *Pentium*III*Mobile*)
+ cpu_arg="pentium3m";
;;
- *Pentium*III*CPU*)
- cpu_flag="pentium3";
+ *Pentium*III*)
+ cpu_arg="pentium3";
;;
*Pentium*M*pro*)
- cpu_flag="pentium-m";
- cpu_flag_old="pentium";
+ cpu_arg="pentium-m";
;;
*Athlon*64*)
- cpu_flag="athlon64";
- cpu_flag_old="athlon";
+ cpu_arg="athlon64";
;;
*Athlon*)
- cpu_flag="athlon";
+ cpu_arg="athlon";
;;
+
+ # Intel ia64
*Itanium*)
# Don't need to set any flags for itanium(at the moment)
- cpu_flag="";
+ cpu_arg="";
;;
- *ppc)
- cpu_flag="powerpc";
- no_march=1;
+
+ #
+ *powerpc*)
+ cpu_arg=`echo $model_name | sed -e"s/ppc//g"`
;;
+
+ # unknown
*)
- cpu_flag="";
+ cpu_arg="";
;;
esac
-if test -z "$cpu_flag"; then
+
+if test -z "$cpu_arg"; then
echo "BUILD/check-cpu: Oops, could not findout what kind of cpu this machine is using."
- check_cpu_flags=""
+ check_cpu_cflags=""
return
fi
-echo "cpu_flag: $cpu_flag"
-
+# 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*--3.4*|*GCC*--3.5*|*GCC*--4.*)
- check_cpu_cflags="-mtune=$cpu_flag -march=$cpu_flag"
- ;;
*GCC*)
- # Fix for older compiler versions
- if test -n "$cpu_flag_old"; then
- cpu_flag="$cpu_flag_old"
- fi
- check_cpu_cflags="-mcpu=$cpu_flag -march=$cpu_flag"
- if test -n "$no_march"; then
- check_cpu_cflags="-mcpu=$cpu_flag"
- fi
+ # 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
-echo $check_cpu_cflags
+
+# 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=""
+
+ # 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.*
+
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index a559e0f9b0d..5d06a8aac73 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -88,6 +88,7 @@ hf@deer.mysql.r18.ru
hf@genie.(none)
holyfoot@mysql.com
igor@hundin.mysql.fi
+igor@igor-inspiron.creware.com
igor@linux.local
igor@rurik.mysql.com
ingo@mysql.com
@@ -239,6 +240,7 @@ rburnett@bk-internal.mysql.com
rburnett@build.mysql.com
reggie@bob.(none)
reggie@mdk10.(none)
+reggie@monster.
root@home.(none)
root@mc04.(none)
root@x3.internalnet
diff --git a/VC++Files/client/mysql.dsp b/VC++Files/client/mysql.dsp
index 8298e62d8ad..e9e79a49d0a 100644
--- a/VC++Files/client/mysql.dsp
+++ b/VC++Files/client/mysql.dsp
@@ -52,7 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_release/mysql.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_release/mysql.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /incremental:yes
!ELSEIF "$(CFG)" == "mysql - Win32 Debug"
@@ -78,7 +78,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysql.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysql.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
!ELSEIF "$(CFG)" == "mysql - Win32 classic"
@@ -104,9 +104,9 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
-# ADD BASE LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_release/mysql.exe" /libpath:"..\lib_release\\"
+# ADD BASE LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_release/mysql.exe" /libpath:"..\lib_release\\"
# SUBTRACT BASE LINK32 /incremental:yes
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_classic/mysql.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /out:"../client_classic/mysql.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /incremental:yes
!ENDIF
diff --git a/VC++Files/client/mysqladmin.dsp b/VC++Files/client/mysqladmin.dsp
index b473d104a76..d713325b4e7 100644
--- a/VC++Files/client/mysqladmin.dsp
+++ b/VC++Files/client/mysqladmin.dsp
@@ -52,7 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqladmin.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqladmin.exe" /libpath:"..\lib_release\\"
!ELSEIF "$(CFG)" == "mysqladmin - Win32 Debug"
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqladmin.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqladmin.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
!ELSEIF "$(CFG)" == "mysqladmin - Win32 classic"
@@ -104,7 +104,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqladmin.exe" /libpath:"..\lib_release\\"
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysqladmin.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysqladmin.exe" /libpath:"..\lib_release\\"
!ENDIF
diff --git a/VC++Files/client/mysqlimport.dsp b/VC++Files/client/mysqlimport.dsp
index 1a9b64a0383..1b650dab731 100644
--- a/VC++Files/client/mysqlimport.dsp
+++ b/VC++Files/client/mysqlimport.dsp
@@ -52,7 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlimport.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlimport.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /incremental:yes
!ELSEIF "$(CFG)" == "mysqlimport - Win32 Debug"
@@ -78,7 +78,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlimport.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib setargv.obj /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlimport.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
!ELSEIF "$(CFG)" == "mysqlimport - Win32 classic"
@@ -104,9 +104,9 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
-# ADD BASE LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlimport.exe" /libpath:"..\lib_release\\"
+# ADD BASE LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlimport.exe" /libpath:"..\lib_release\\"
# SUBTRACT BASE LINK32 /incremental:yes
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysqlimport.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysqlimport.exe" /libpath:"..\lib_release\\"
# SUBTRACT LINK32 /incremental:yes
!ENDIF
diff --git a/VC++Files/client/mysqlshow.dsp b/VC++Files/client/mysqlshow.dsp
index 855c2dcdf34..f9377763c49 100644
--- a/VC++Files/client/mysqlshow.dsp
+++ b/VC++Files/client/mysqlshow.dsp
@@ -52,7 +52,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlshow.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlshow.exe" /libpath:"..\lib_release\\"
!ELSEIF "$(CFG)" == "mysqlshow - Win32 Debug"
@@ -77,7 +77,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlshow.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../client_debug/mysqlshow.exe" /pdbtype:sept /libpath:"..\lib_debug\\"
!ELSEIF "$(CFG)" == "mysqlshow - Win32 classic"
@@ -103,8 +103,8 @@ BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=xilink6.exe
-# ADD BASE LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlshow.exe" /libpath:"..\lib_release\\"
-# ADD LINK32 mysqlclient.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysqlshow.exe" /libpath:"..\lib_release\\"
+# ADD BASE LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../client_release/mysqlshow.exe" /libpath:"..\lib_release\\"
+# ADD LINK32 mysqlclient.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib zlib.lib /nologo /subsystem:console /machine:I386 /out:"../client_classic/mysqlshow.exe" /libpath:"..\lib_release\\"
!ENDIF
diff --git a/VC++Files/libmysql/libmysql.dsp b/VC++Files/libmysql/libmysql.dsp
index 473aa60d8af..4f93ac93c40 100644
--- a/VC++Files/libmysql/libmysql.dsp
+++ b/VC++Files/libmysql/libmysql.dsp
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
-# ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"..\lib_release\libmysql.dll" /libpath:"." /libpath:"..\lib_release"
+# ADD LINK32 mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"libmysql.def" /out:"..\lib_release\libmysql.dll" /libpath:"." /libpath:"..\lib_release"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
@@ -87,7 +87,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 zlib.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"..\lib_debug\libmysql.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
+# ADD LINK32 zlib.lib mysys.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /map /debug /machine:I386 /def:"libmysql.def" /out:"..\lib_debug\libmysql.dll" /pdbtype:sept /libpath:"." /libpath:"..\lib_debug"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
diff --git a/VC++Files/mysql.dsw b/VC++Files/mysql.dsw
index 25bcab8338b..6ebda999c35 100644
--- a/VC++Files/mysql.dsw
+++ b/VC++Files/mysql.dsw
@@ -80,6 +80,9 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
}}}
###############################################################################
@@ -320,6 +323,9 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name zlib
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
}}}
###############################################################################
@@ -476,6 +482,9 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name mysqlclient
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
}}}
###############################################################################
@@ -533,6 +542,9 @@ Package=<4>
Begin Project Dependency
Project_Dep_Name mysqlclient
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name mysys
+ End Project Dependency
}}}
###############################################################################
diff --git a/client/mysql.cc b/client/mysql.cc
index 9cdc270e8ed..ca021cd11f0 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -44,7 +44,7 @@
#include <locale.h>
#endif
-const char *VER= "14.10";
+const char *VER= "14.11";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -1917,7 +1917,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
time_buff[0]=0;
if (result)
{
- if (!mysql_num_rows(result) && ! quick)
+ if (!mysql_num_rows(result) && ! quick && !info_flag)
{
strmov(buff, "Empty set");
}
@@ -2049,18 +2049,93 @@ com_ego(String *buffer,char *line)
return result;
}
+static char *fieldtype2str(enum enum_field_types type) {
+ switch(type) {
+ case FIELD_TYPE_BIT: return "BIT";
+ case FIELD_TYPE_BLOB: return "BLOB";
+ case FIELD_TYPE_DATE: return "DATE";
+ case FIELD_TYPE_DATETIME: return "DATETIME";
+ case FIELD_TYPE_NEWDECIMAL: return "NEWDECIMAL";
+ case FIELD_TYPE_DECIMAL: return "DECIMAL";
+ case FIELD_TYPE_DOUBLE: return "DOUBLE";
+ case FIELD_TYPE_ENUM: return "ENUM";
+ case FIELD_TYPE_FLOAT: return "FLOAT";
+ case FIELD_TYPE_GEOMETRY: return "GEOMETRY";
+ case FIELD_TYPE_INT24: return "INT24";
+ case FIELD_TYPE_LONG: return "LONG";
+ case FIELD_TYPE_LONGLONG: return "LONGLONG";
+ case FIELD_TYPE_LONG_BLOB: return "LONG_BLOB";
+ case FIELD_TYPE_MEDIUM_BLOB: return "MEDIUM_BLOB";
+ case FIELD_TYPE_NEWDATE: return "NEWDATE";
+ case FIELD_TYPE_NULL: return "NULL";
+ case FIELD_TYPE_SET: return "SET";
+ case FIELD_TYPE_SHORT: return "SHORT";
+ case FIELD_TYPE_STRING: return "STRING";
+ case FIELD_TYPE_TIME: return "TIME";
+ case FIELD_TYPE_TIMESTAMP: return "TIMESTAMP";
+ case FIELD_TYPE_TINY: return "TINY";
+ case FIELD_TYPE_TINY_BLOB: return "TINY_BLOB";
+ case FIELD_TYPE_VAR_STRING: return "VAR_STRING";
+ case FIELD_TYPE_YEAR: return "YEAR";
+ default: return "?-unknown-?";
+ }
+}
+
+static char *fieldflags2str(uint f) {
+ static char buf[1024];
+ char *s=buf;
+ *s=0;
+#define ff2s_check_flag(X) \
+ if (f & X ## _FLAG) { s=strmov(s, # X " "); f &= ~ X ## _FLAG; }
+ ff2s_check_flag(NOT_NULL);
+ ff2s_check_flag(PRI_KEY);
+ ff2s_check_flag(UNIQUE_KEY);
+ ff2s_check_flag(MULTIPLE_KEY);
+ ff2s_check_flag(BLOB);
+ ff2s_check_flag(UNSIGNED);
+ ff2s_check_flag(ZEROFILL);
+ ff2s_check_flag(BINARY);
+ ff2s_check_flag(ENUM);
+ ff2s_check_flag(AUTO_INCREMENT);
+ ff2s_check_flag(TIMESTAMP);
+ ff2s_check_flag(SET);
+ ff2s_check_flag(NO_DEFAULT_VALUE);
+ ff2s_check_flag(NUM);
+ ff2s_check_flag(PART_KEY);
+ ff2s_check_flag(GROUP);
+ ff2s_check_flag(UNIQUE);
+ ff2s_check_flag(BINCMP);
+#undef ff2s_check_flag
+ if (f)
+ sprintf(s, " unknows=0x%04x", f);
+ return buf;
+}
+
static void
print_field_types(MYSQL_RES *result)
{
- MYSQL_FIELD *field;
+ MYSQL_FIELD *field;
+ uint i=0;
+
while ((field = mysql_fetch_field(result)))
{
- tee_fprintf(PAGER,"Catalog: '%s'\nDatabase: '%s'\nTable: '%s'\nName: '%s'\nType: %d\nLength: %ld\nMax length: %ld\nIs_null: %d\nFlags: %u\nDecimals: %u\n\n",
- field->catalog, field->db, field->table, field->name,
- (int) field->type,
- field->length, field->max_length,
- !IS_NOT_NULL(field->flags),
- field->flags, field->decimals);
+ tee_fprintf(PAGER, "Field %3u: `%s`\n"
+ "Catalog: `%s`\n"
+ "Database: `%s`\n"
+ "Table: `%s`\n"
+ "Org_table: `%s`\n"
+ "Type: %s\n"
+ "Collation: %s (%u)\n"
+ "Length: %lu\n"
+ "Max_length: %lu\n"
+ "Decimals: %u\n"
+ "Flags: %s\n\n",
+ ++i,
+ field->name, field->catalog, field->db, field->table,
+ field->org_table, fieldtype2str(field->type),
+ get_charset_name(field->charsetnr), field->charsetnr,
+ field->length, field->max_length, field->decimals,
+ fieldflags2str(field->flags));
}
tee_puts("", PAGER);
}
@@ -2078,6 +2153,8 @@ print_table_data(MYSQL_RES *result)
if (info_flag)
{
print_field_types(result);
+ if (!mysql_num_rows(result))
+ return;
mysql_field_seek(result,0);
}
separator.copy("+",1,charset_info);
diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4
index ada1a2c0bd1..ddacde51c2a 100644
--- a/config/ac-macros/yassl.m4
+++ b/config/ac-macros/yassl.m4
@@ -19,8 +19,8 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [
AC_MSG_RESULT([using bundled yaSSL])
yassl_dir="extra/yassl"
openssl_libs="\
- \$(top_builddir)/extra/yassl/src/libyassl.a\
- \$(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.a"
+ -L\$(top_builddir)/extra/yassl/src -lyassl\
+ -L\$(top_builddir)/extra/yassl/taocrypt/src -ltaocrypt"
openssl_includes="-I\$(top_srcdir)/extra/yassl/include"
AC_DEFINE([HAVE_OPENSSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.])
else
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index 466884f3cd9..84ffb9b5829 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -36,7 +36,7 @@
#include "handshake.hpp"
#include "yassl_int.hpp"
#include <stdio.h>
-
+#include "runtime.hpp"
namespace yaSSL {
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index 67f3c963cac..deea376189c 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -3940,7 +3940,10 @@ Integer CRT(const Integer &xp, const Integer &p, const Integer &xq,
}
#ifdef __GNUC__
-template unsigned int DivideThreeWordsByTwo<unsigned int, DWord>(unsigned int*, unsigned int, unsigned int, DWord*);
+#ifndef TAOCRYPT_NATIVE_DWORD_AVAILABLE
+template hword DivideThreeWordsByTwo<hword, Word>(hword*, hword, hword, Word*);
+#endif
+template word DivideThreeWordsByTwo<word, DWord>(word*, word, word, DWord*);
#endif
} // namespace
diff --git a/extra/yassl/taocrypt/src/template_instnt.cpp b/extra/yassl/taocrypt/src/template_instnt.cpp
index 28dbdc5c739..81a8273c5c3 100644
--- a/extra/yassl/taocrypt/src/template_instnt.cpp
+++ b/extra/yassl/taocrypt/src/template_instnt.cpp
@@ -9,23 +9,27 @@ namespace TaoCrypt {
#if defined(SSE2_INTRINSICS_AVAILABLE)
template AlignedAllocator<unsigned int>::pointer StdReallocate<unsigned int, AlignedAllocator<unsigned int> >(AlignedAllocator<unsigned int>&, unsigned int*, AlignedAllocator<unsigned int>::size_type, AlignedAllocator<unsigned int>::size_type, bool);
#endif
-template AllocatorWithCleanup<unsigned char>::pointer StdReallocate<unsigned char, AllocatorWithCleanup<unsigned char> >(AllocatorWithCleanup<unsigned char>&, unsigned char*, AllocatorWithCleanup<unsigned char>::size_type, AllocatorWithCleanup<unsigned char>::size_type, bool);
-template AllocatorWithCleanup<unsigned int>::pointer StdReallocate<unsigned int, AllocatorWithCleanup<unsigned int> >(AllocatorWithCleanup<unsigned int>&, unsigned int*, AllocatorWithCleanup<unsigned int>::size_type, AllocatorWithCleanup<unsigned int>::size_type, bool);
template class RSA_Decryptor<RSA_BlockType2>;
template class RSA_Encryptor<RSA_BlockType1>;
template class RSA_Encryptor<RSA_BlockType2>;
+template void tcDelete<HASH>(HASH*);
+template void tcArrayDelete<byte>(byte*);
+template AllocatorWithCleanup<byte>::pointer StdReallocate<byte, AllocatorWithCleanup<byte> >(AllocatorWithCleanup<byte>&, byte*, AllocatorWithCleanup<byte>::size_type, AllocatorWithCleanup<byte>::size_type, bool);
+template void tcArrayDelete<word>(word*);
+template AllocatorWithCleanup<word>::pointer StdReallocate<word, AllocatorWithCleanup<word> >(AllocatorWithCleanup<word>&, word*, AllocatorWithCleanup<word>::size_type, AllocatorWithCleanup<word>::size_type, bool);
+#ifndef TAOCRYPT_SLOW_WORD64 // defined when word != word32
+template void tcArrayDelete<word32>(word32*);
+template AllocatorWithCleanup<word32>::pointer StdReallocate<word32, AllocatorWithCleanup<word32> >(AllocatorWithCleanup<word32>&, word32*, AllocatorWithCleanup<word32>::size_type, AllocatorWithCleanup<word32>::size_type, bool);
+#endif
+template void tcArrayDelete<char>(char*);
}
namespace mySTL {
-template vector<TaoCrypt::Integer>* uninit_fill_n<vector<TaoCrypt::Integer>*, unsigned int, vector<TaoCrypt::Integer> >(vector<TaoCrypt::Integer>*, unsigned int, vector<TaoCrypt::Integer> const&);
+template vector<TaoCrypt::Integer>* uninit_fill_n<vector<TaoCrypt::Integer>*, size_t, vector<TaoCrypt::Integer> >(vector<TaoCrypt::Integer>*, size_t, vector<TaoCrypt::Integer> const&);
template void destroy<vector<TaoCrypt::Integer>*>(vector<TaoCrypt::Integer>*, vector<TaoCrypt::Integer>*);
template TaoCrypt::Integer* uninit_copy<TaoCrypt::Integer*, TaoCrypt::Integer*>(TaoCrypt::Integer*, TaoCrypt::Integer*, TaoCrypt::Integer*);
-template TaoCrypt::Integer* uninit_fill_n<TaoCrypt::Integer*, unsigned int, TaoCrypt::Integer>(TaoCrypt::Integer*, unsigned int, TaoCrypt::Integer const&);
+template TaoCrypt::Integer* uninit_fill_n<TaoCrypt::Integer*, size_t, TaoCrypt::Integer>(TaoCrypt::Integer*, size_t, TaoCrypt::Integer const&);
template void destroy<TaoCrypt::Integer*>(TaoCrypt::Integer*, TaoCrypt::Integer*);
}
-template void TaoCrypt::tcDelete<TaoCrypt::HASH>(TaoCrypt::HASH*);
-template void TaoCrypt::tcArrayDelete<unsigned>(unsigned*);
-template void TaoCrypt::tcArrayDelete<unsigned char>(unsigned char*);
-template void TaoCrypt::tcArrayDelete<char>(char*);
#endif
diff --git a/include/config-win.h b/include/config-win.h
index bc14d3d3e53..b17e4df4e26 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -76,6 +76,7 @@ functions */
#define F_EXCLUSIVE 1 /* We have only exclusive locking */
#define F_TO_EOF (INT_MAX32/2) /* size for lock of all file */
#define F_OK 0 /* parameter to access() */
+#define W_OK 2
#define S_IROTH S_IREAD /* for my_lib */
diff --git a/include/mysql.h b/include/mysql.h
index b2b2e239758..84284fa0661 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -74,14 +74,14 @@ extern char *mysql_unix_port;
#define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG)
#define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG)
#define IS_BLOB(n) ((n) & BLOB_FLAG)
-#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR)
+#define IS_NUM(t) ((t) <= FIELD_TYPE_INT24 || (t) == FIELD_TYPE_YEAR || (t) == FIELD_TYPE_NEWDECIMAL)
#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG)
#define INTERNAL_NUM_FIELD(f) (((f)->type <= FIELD_TYPE_INT24 && ((f)->type != FIELD_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == FIELD_TYPE_YEAR)
typedef struct st_mysql_field {
char *name; /* Name of column */
- char *org_name; /* Original column name, if an alias */
+ char *org_name; /* Original column name, if an alias */
char *table; /* Table of column if column was a field */
char *org_table; /* Org table name, if table was an alias */
char *db; /* Database for table */
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index c87728ab783..d294921aad2 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2809,11 +2809,14 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
{
switch (attr_type) {
case STMT_ATTR_UPDATE_MAX_LENGTH:
- *(unsigned long *) value= stmt->update_max_length;
+ *(ulong*) value= stmt->update_max_length;
break;
case STMT_ATTR_CURSOR_TYPE:
- *(unsigned long *) value= stmt->flags;
+ *(ulong*) value= stmt->flags;
break;
+ case STMT_ATTR_PREFETCH_ROWS:
+ *(ulong*) value= stmt->prefetch_rows;
+ break;
default:
return TRUE;
}
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 776bcb4de69..12bae21a5a0 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -86,29 +86,24 @@ INC_LIB= $(top_builddir)/regex/libregex.a \
# To make it easy for the end user to use the embedded library we
# generate a total libmysqld.a from all library files,
+# note - InnoDB libraries have circular dependencies, so in INC_LIB
+# few libraries are present two times. Metrowerks linker doesn't like
+# it at all. Traditional ar has no problems with it, but still there's no
+# need to add the same file twice to the library, so 'sort -u' save us
+# some time and spares unnecessary work.
+
libmysqld.a: libmysqld_int.a $(INC_LIB)
if DARWIN_MWCC
- mwld -lib -o $@ libmysqld_int.a `ls -1 $(INC_LIB) | sort -u`
+ mwld -lib -o $@ libmysqld_int.a `echo $(INC_LIB) | sort -u`
else
if test "$(host_os)" = "netware" ; \
then \
$(libmysqld_a_AR) libmysqld.a libmysqld_int.a $(INC_LIB) ; \
else \
- if test ! -d tmp ; then mkdir tmp ; fi ; \
- rm -f $@ libmysqld_int2.a tmp/*.o tmp/*.a ; \
- cp $(INC_LIB) tmp ; \
- cp libmysqld_int.a libmysqld_int2.a ; \
- cd tmp ; \
- for file in *.a ; do \
- bfile=`basename $$file .a` ; \
- $(AR) x $$file; \
- for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
- $(AR) q ../libmysqld_int2.a *.o ; \
- rm -f *.o ; \
- done ; \
- cd .. ; \
- mv libmysqld_int2.a libmysqld.a ; \
- rm -f tmp/* ; \
+ for arc in ./libmysqld_int.a $(INC_LIB); do \
+ arpath=`echo $$arc|sed 's|[^/]*$$||'`; \
+ $(AR) t $$arc|sed "s|^|$$arpath|"; \
+ done | sort -u | xargs $(AR) cq libmysqld.a ; \
$(RANLIB) libmysqld.a ; \
fi
endif
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 5fb21004469..a854cf4c7b0 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -160,3 +160,20 @@ t1 CREATE TABLE `t1` (
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+CREATE TABLE t1 (EMPNUM INT);
+INSERT INTO t1 VALUES (0), (2);
+CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
+INSERT INTO t2 VALUES (0.0), (9.0);
+SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
+t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
+FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
+CEMPNUM EMPMUM1 EMPNUM2
+0.00 0 0.00
+2.00 2 NULL
+SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
+t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
+FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
+CEMPNUM EMPMUM1 EMPNUM2
+0.00 0 0.00
+2.00 2 NULL
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 8ab24fe550b..4be9139f20b 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -888,3 +888,6 @@ NULL
select ifnull(NULL, _utf8'string');
ifnull(NULL, _utf8'string')
string
+create table t1 (a varchar(255)) default character set utf8;
+insert into t1 values (1.0);
+drop table t1;
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index 4db31121756..3e72fb45a14 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -91,3 +91,20 @@ drop table t1;
SELECT NULLIF(5,5) IS NULL, NULLIF(5,5) IS NOT NULL;
NULLIF(5,5) IS NULL NULLIF(5,5) IS NOT NULL
1 0
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL ,
+`date` int(10) default NULL,
+`text` varchar(32) NOT NULL
+);
+INSERT INTO t1 VALUES (1,1110000000,'Day 1'),(2,1111000000,'Day 2'),(3,1112000000,'Day 3');
+SELECT id, IF(date IS NULL, '-', FROM_UNIXTIME(date, '%d-%m-%Y')) AS date_ord, text FROM t1 ORDER BY date_ord ASC;
+id date_ord text
+1 05-03-2005 Day 1
+2 16-03-2005 Day 2
+3 28-03-2005 Day 3
+SELECT id, IF(date IS NULL, '-', FROM_UNIXTIME(date, '%d-%m-%Y')) AS date_ord, text FROM t1 ORDER BY date_ord DESC;
+id date_ord text
+3 28-03-2005 Day 3
+2 16-03-2005 Day 2
+1 05-03-2005 Day 1
+DROP TABLE t1;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 4293ef5bd85..239fca65b67 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -688,3 +688,6 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select timestamp_diff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestamp_diff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2`
+select time_format('100:00:00', '%H %k %h %I %l');
+time_format('100:00:00', '%H %k %h %I %l')
+100 100 04 04 4
diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result
index 7f769154212..14cd4666528 100644
--- a/mysql-test/r/ndb_condition_pushdown.result
+++ b/mysql-test/r/ndb_condition_pushdown.result
@@ -251,6 +251,213 @@ auto
1
3
4
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+(bits between b'001' and b'011') and
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+(b'001' between bits and bits) and
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+auto
+1
+select auto from t1 where
+(string not between "aaaa" and "cccc") and
+(vstring not between "aaaa" and "cccc") and
+(bin not between 0xAAAA and 0xCCCC) and
+(vbin not between 0xAAAA and 0xCCCC) and
+(tiny not between -3 and -1) and
+(short not between -3 and -1) and
+(medium not between -3 and -1) and
+(long_int not between -3 and -1) and
+(longlong not between -3 and -1) and
+(utiny not between 1 and 3) and
+(ushort not between 1 and 3) and
+(umedium not between 1 and 3) and
+(ulong not between 1 and 3) and
+(ulonglong not between 1 and 3) and
+(bits not between b'001' and b'011') and
+(options not between 'one' and 'three') and
+(flags not between 'one' and 'one,two,three') and
+(date_field not between '1901-01-01' and '1903-03-03') and
+(year_field not between '1901' and '1903') and
+(time_field not between '01:01:01' and '03:03:03') and
+(date_time not between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+auto
+4
+select auto from t1 where
+("aaaa" not between string and string) and
+("aaaa" not between vstring and vstring) and
+(0xAAAA not between bin and bin) and
+(0xAAAA not between vbin and vbin) and
+(-1 not between tiny and tiny) and
+(-1 not between short and short) and
+(-1 not between medium and medium) and
+(-1 not between long_int and long_int) and
+(-1 not between longlong and longlong) and
+(1 not between utiny and utiny) and
+(1 not between ushort and ushort) and
+(1 not between umedium and umedium) and
+(1 not between ulong and ulong) and
+(1 not between ulonglong and ulonglong) and
+(b'001' not between bits and bits) and
+('one' not between options and options) and
+('one' not between flags and flags) and
+('1901-01-01' not between date_field and date_field) and
+('1901' not between year_field and year_field) and
+('01:01:01' not between time_field and time_field) and
+('1901-01-01 01:01:01' not between date_time and date_time)
+order by auto;
+auto
+2
+3
+4
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+bits in(b'001',b'011') and
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+(-1 in(tiny)) and
+(-1 in(short)) and
+(-1 in(medium)) and
+(-1 in(long_int)) and
+(-1 in(longlong)) and
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+b'001' in(bits) and
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+auto
+1
+select auto from t1 where
+string not in("aaaa","cccc") and
+vstring not in("aaaa","cccc") and
+bin not in(0xAAAA,0xCCCC) and
+vbin not in(0xAAAA,0xCCCC) and
+tiny not in(-1,-3) and
+short not in(-1,-3) and
+medium not in(-1,-3) and
+long_int not in(-1,-3) and
+longlong not in(-1,-3) and
+utiny not in(1,3) and
+ushort not in(1,3) and
+umedium not in(1,3) and
+ulong not in(1,3) and
+ulonglong not in(1,3) and
+bits not in(b'001',b'011') and
+options not in('one','three') and
+flags not in('one','one,two,three') and
+date_field not in('1901-01-01','1903-03-03') and
+year_field not in('1901','1903') and
+time_field not in('01:01:01','03:03:03') and
+date_time not in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+auto
+2
+4
+select auto from t1 where
+"aaaa" not in(string) and
+"aaaa" not in(vstring) and
+0xAAAA not in(bin) and
+0xAAAA not in(vbin) and
+(-1 not in(tiny)) and
+(-1 not in(short)) and
+(-1 not in(medium)) and
+(-1 not in(long_int)) and
+(-1 not in(longlong)) and
+1 not in(utiny) and
+1 not in(ushort) and
+1 not in(umedium) and
+1 not in(ulong) and
+1 not in(ulonglong) and
+b'001' not in(bits) and
+'one' not in(options) and
+'one' not in(flags) and
+'1901-01-01' not in(date_field) and
+'1901' not in(year_field) and
+'01:01:01' not in(time_field) and
+'1901-01-01 01:01:01' not in(date_time)
+order by auto;
+auto
+2
+3
+4
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
pk1 attr1 attr2 attr3
2 2 NULL NULL
@@ -1023,6 +1230,421 @@ auto
1
3
4
+explain
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range medium_index medium_index 3 NULL 10 Using where with pushed condition; Using filesort
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+explain
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+auto
+1
+explain
+select auto from t1 where
+(string not between "aaaa" and "cccc") and
+(vstring not between "aaaa" and "cccc") and
+(bin not between 0xAAAA and 0xCCCC) and
+(vbin not between 0xAAAA and 0xCCCC) and
+(tiny not between -3 and -1) and
+(short not between -3 and -1) and
+(medium not between -3 and -1) and
+(long_int not between -3 and -1) and
+(longlong not between -3 and -1) and
+(utiny not between 1 and 3) and
+(ushort not between 1 and 3) and
+(umedium not between 1 and 3) and
+(ulong not between 1 and 3) and
+(ulonglong not between 1 and 3) and
+/* (bits not between b'001' and b'011') and */
+(options not between 'one' and 'three') and
+(flags not between 'one' and 'one,two,three') and
+(date_field not between '1901-01-01' and '1903-03-03') and
+(year_field not between '1901' and '1903') and
+(time_field not between '01:01:01' and '03:03:03') and
+(date_time not between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range medium_index medium_index 3 NULL 20 Using where with pushed condition; Using filesort
+select auto from t1 where
+(string not between "aaaa" and "cccc") and
+(vstring not between "aaaa" and "cccc") and
+(bin not between 0xAAAA and 0xCCCC) and
+(vbin not between 0xAAAA and 0xCCCC) and
+(tiny not between -3 and -1) and
+(short not between -3 and -1) and
+(medium not between -3 and -1) and
+(long_int not between -3 and -1) and
+(longlong not between -3 and -1) and
+(utiny not between 1 and 3) and
+(ushort not between 1 and 3) and
+(umedium not between 1 and 3) and
+(ulong not between 1 and 3) and
+(ulonglong not between 1 and 3) and
+/* (bits not between b'001' and b'011') and */
+(options not between 'one' and 'three') and
+(flags not between 'one' and 'one,two,three') and
+(date_field not between '1901-01-01' and '1903-03-03') and
+(year_field not between '1901' and '1903') and
+(time_field not between '01:01:01' and '03:03:03') and
+(date_time not between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+auto
+4
+explain
+select auto from t1 where
+("aaaa" not between string and string) and
+("aaaa" not between vstring and vstring) and
+(0xAAAA not between bin and bin) and
+(0xAAAA not between vbin and vbin) and
+(-1 not between tiny and tiny) and
+(-1 not between short and short) and
+(-1 not between medium and medium) and
+(-1 not between long_int and long_int) and
+(-1 not between longlong and longlong) and
+(1 not between utiny and utiny) and
+(1 not between ushort and ushort) and
+(1 not between umedium and umedium) and
+(1 not between ulong and ulong) and
+(1 not between ulonglong and ulonglong) and
+/* (b'001' not between bits and bits) and */
+('one' not between options and options) and
+('one' not between flags and flags) and
+('1901-01-01' not between date_field and date_field) and
+('1901' not between year_field and year_field) and
+('01:01:01' not between time_field and time_field) and
+('1901-01-01 01:01:01' not between date_time and date_time)
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort
+select auto from t1 where
+("aaaa" not between string and string) and
+("aaaa" not between vstring and vstring) and
+(0xAAAA not between bin and bin) and
+(0xAAAA not between vbin and vbin) and
+(-1 not between tiny and tiny) and
+(-1 not between short and short) and
+(-1 not between medium and medium) and
+(-1 not between long_int and long_int) and
+(-1 not between longlong and longlong) and
+(1 not between utiny and utiny) and
+(1 not between ushort and ushort) and
+(1 not between umedium and umedium) and
+(1 not between ulong and ulong) and
+(1 not between ulonglong and ulonglong) and
+/* (b'001' not between bits and bits) and */
+('one' not between options and options) and
+('one' not between flags and flags) and
+('1901-01-01' not between date_field and date_field) and
+('1901' not between year_field and year_field) and
+('01:01:01' not between time_field and time_field) and
+('1901-01-01 01:01:01' not between date_time and date_time)
+order by auto;
+auto
+2
+3
+4
+explain
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range medium_index medium_index 3 NULL 20 Using where with pushed condition; Using filesort
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+auto
+1
+3
+explain
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+(-1 in(tiny)) and
+(-1 in (short)) and
+(-1 in(medium)) and
+(-1 in(long_int)) and
+(-1 in(longlong)) and
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+(-1 in(tiny)) and
+(-1 in (short)) and
+(-1 in(medium)) and
+(-1 in(long_int)) and
+(-1 in(longlong)) and
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+auto
+1
+explain
+select auto from t1 where
+string not in("aaaa","cccc") and
+vstring not in("aaaa","cccc") and
+bin not in(0xAAAA,0xCCCC) and
+vbin not in(0xAAAA,0xCCCC) and
+tiny not in(-1,-3) and
+short not in(-1,-3) and
+medium not in(-1,-3) and
+long_int not in(-1,-3) and
+longlong not in(-1,-3) and
+utiny not in(1,3) and
+ushort not in(1,3) and
+umedium not in(1,3) and
+ulong not in(1,3) and
+ulonglong not in(1,3) and
+/* bits not in(b'001',b'011') and */
+options not in('one','three') and
+flags not in('one','one,two,three') and
+date_field not in('1901-01-01','1903-03-03') and
+year_field not in('1901','1903') and
+time_field not in('01:01:01','03:03:03') and
+date_time not in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range medium_index medium_index 3 NULL 30 Using where with pushed condition; Using filesort
+select auto from t1 where
+string not in("aaaa","cccc") and
+vstring not in("aaaa","cccc") and
+bin not in(0xAAAA,0xCCCC) and
+vbin not in(0xAAAA,0xCCCC) and
+tiny not in(-1,-3) and
+short not in(-1,-3) and
+medium not in(-1,-3) and
+long_int not in(-1,-3) and
+longlong not in(-1,-3) and
+utiny not in(1,3) and
+ushort not in(1,3) and
+umedium not in(1,3) and
+ulong not in(1,3) and
+ulonglong not in(1,3) and
+/* bits not in(b'001',b'011') and */
+options not in('one','three') and
+flags not in('one','one,two,three') and
+date_field not in('1901-01-01','1903-03-03') and
+year_field not in('1901','1903') and
+time_field not in('01:01:01','03:03:03') and
+date_time not in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+auto
+2
+4
+explain
+select auto from t1 where
+"aaaa" not in(string) and
+"aaaa" not in(vstring) and
+0xAAAA not in(bin) and
+0xAAAA not in(vbin) and
+(-1 not in(tiny)) and
+(-1 not in(short)) and
+(-1 not in(medium)) and
+(-1 not in(long_int)) and
+(-1 not in(longlong)) and
+1 not in(utiny) and
+1 not in(ushort) and
+1 not in(umedium) and
+1 not in(ulong) and
+1 not in(ulonglong) and
+/* b'001' not in(bits) and */
+'one' not in(options) and
+'one' not in(flags) and
+'1901-01-01' not in(date_field) and
+'1901' not in(year_field) and
+'01:01:01' not in(time_field) and
+'1901-01-01 01:01:01' not in(date_time)
+order by auto;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where with pushed condition; Using filesort
+select auto from t1 where
+"aaaa" not in(string) and
+"aaaa" not in(vstring) and
+0xAAAA not in(bin) and
+0xAAAA not in(vbin) and
+(-1 not in(tiny)) and
+(-1 not in(short)) and
+(-1 not in(medium)) and
+(-1 not in(long_int)) and
+(-1 not in(longlong)) and
+1 not in(utiny) and
+1 not in(ushort) and
+1 not in(umedium) and
+1 not in(ulong) and
+1 not in(ulonglong) and
+/* b'001' not in(bits) and */
+'one' not in(options) and
+'one' not in(flags) and
+'1901-01-01' not in(date_field) and
+'1901' not in(year_field) and
+'01:01:01' not in(time_field) and
+'1901-01-01 01:01:01' not in(date_time)
+order by auto;
+auto
+2
+3
+4
update t1
set medium = 17
where
@@ -1139,5 +1761,10 @@ explain
select * from t2 where (attr1 < 2) = (attr2 < 2) order by pk1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 6 Using where; Using filesort
+explain
+select * from t3 left join t4 on t4.attr2 = t3.attr2 where t4.attr1 > 1 and t4.attr3 < 5 or t4.attr1 is null order by t4.pk1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+1 SIMPLE t4 ALL NULL NULL NULL NULL 6 Using where
set engine_condition_pushdown = @old_ecpd;
DROP TABLE t1,t2,t3,t4;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index c7f980df350..99b4f0529e6 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -236,6 +236,12 @@ query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
+SELECT @@version LIKE 'non-existent';
+@@version LIKE 'non-existent'
+0
+SELECT @@version_compile_os LIKE 'non-existent';
+@@version_compile_os LIKE 'non-existent'
+0
set big_tables=OFFF;
ERROR 42000: Variable 'big_tables' can't be set to the value of 'OFFF'
set big_tables="OFFF";
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index fed3ff07a13..f2cfce9085d 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -110,3 +110,22 @@ explain extended SELECT
COALESCE('a' COLLATE latin1_bin,'b');
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+#
+# Tests for bug #9939: conversion of the arguments for COALESCE and IFNULL
+#
+
+CREATE TABLE t1 (EMPNUM INT);
+INSERT INTO t1 VALUES (0), (2);
+CREATE TABLE t2 (EMPNUM DECIMAL (4, 2));
+INSERT INTO t2 VALUES (0.0), (9.0);
+
+SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
+ t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
+ FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
+
+SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
+ t1.EMPNUM AS EMPMUM1, t2.EMPNUM AS EMPNUM2
+ FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 02024adb34e..bac6e60c302 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -724,3 +724,10 @@ select ifnull(a,'') from t1;
drop table t1;
select repeat(_utf8'+',3) as h union select NULL;
select ifnull(NULL, _utf8'string');
+
+#
+# Bug#10714: Inserting double value into utf8 column crashes server
+#
+create table t1 (a varchar(255)) default character set utf8;
+insert into t1 values (1.0);
+drop table t1;
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index a2ea26390ca..37556984f68 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -61,3 +61,17 @@ drop table t1;
# Bug #5595 NULLIF() IS NULL returns false if NULLIF() returns NULL
#
SELECT NULLIF(5,5) IS NULL, NULLIF(5,5) IS NOT NULL;
+
+#
+# Bug #9669 Ordering on IF function with FROM_UNIXTIME function fails
+#
+CREATE TABLE `t1` (
+ `id` int(11) NOT NULL ,
+ `date` int(10) default NULL,
+ `text` varchar(32) NOT NULL
+);
+INSERT INTO t1 VALUES (1,1110000000,'Day 1'),(2,1111000000,'Day 2'),(3,1112000000,'Day 3');
+SELECT id, IF(date IS NULL, '-', FROM_UNIXTIME(date, '%d-%m-%Y')) AS date_ord, text FROM t1 ORDER BY date_ord ASC;
+SELECT id, IF(date IS NULL, '-', FROM_UNIXTIME(date, '%d-%m-%Y')) AS date_ord, text FROM t1 ORDER BY date_ord DESC;
+DROP TABLE t1;
+
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 80ddb205110..34da2ae1435 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -336,3 +336,9 @@ DROP TABLE t1;
explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1,
timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2;
+
+#
+# Bug #10590: %h, %I, and %l format specifies should all return results in
+# the 0-11 range
+#
+select time_format('100:00:00', '%H %k %h %I %l');
diff --git a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test
index 1d201a94c95..d090d12e81b 100644
--- a/mysql-test/t/ndb_condition_pushdown.test
+++ b/mysql-test/t/ndb_condition_pushdown.test
@@ -249,6 +249,202 @@ bin not like concat(0xBB, '%') and
vbin not like concat(0xBB, '%')
order by auto;
+# BETWEEN
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+(bits between b'001' and b'011') and
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+(b'001' between bits and bits) and
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+
+# NOT BETWEEN
+select auto from t1 where
+(string not between "aaaa" and "cccc") and
+(vstring not between "aaaa" and "cccc") and
+(bin not between 0xAAAA and 0xCCCC) and
+(vbin not between 0xAAAA and 0xCCCC) and
+(tiny not between -3 and -1) and
+(short not between -3 and -1) and
+(medium not between -3 and -1) and
+(long_int not between -3 and -1) and
+(longlong not between -3 and -1) and
+(utiny not between 1 and 3) and
+(ushort not between 1 and 3) and
+(umedium not between 1 and 3) and
+(ulong not between 1 and 3) and
+(ulonglong not between 1 and 3) and
+(bits not between b'001' and b'011') and
+(options not between 'one' and 'three') and
+(flags not between 'one' and 'one,two,three') and
+(date_field not between '1901-01-01' and '1903-03-03') and
+(year_field not between '1901' and '1903') and
+(time_field not between '01:01:01' and '03:03:03') and
+(date_time not between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+("aaaa" not between string and string) and
+("aaaa" not between vstring and vstring) and
+(0xAAAA not between bin and bin) and
+(0xAAAA not between vbin and vbin) and
+(-1 not between tiny and tiny) and
+(-1 not between short and short) and
+(-1 not between medium and medium) and
+(-1 not between long_int and long_int) and
+(-1 not between longlong and longlong) and
+(1 not between utiny and utiny) and
+(1 not between ushort and ushort) and
+(1 not between umedium and umedium) and
+(1 not between ulong and ulong) and
+(1 not between ulonglong and ulonglong) and
+(b'001' not between bits and bits) and
+('one' not between options and options) and
+('one' not between flags and flags) and
+('1901-01-01' not between date_field and date_field) and
+('1901' not between year_field and year_field) and
+('01:01:01' not between time_field and time_field) and
+('1901-01-01 01:01:01' not between date_time and date_time)
+order by auto;
+
+# IN
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+bits in(b'001',b'011') and
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+(-1 in(tiny)) and
+(-1 in(short)) and
+(-1 in(medium)) and
+(-1 in(long_int)) and
+(-1 in(longlong)) and
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+b'001' in(bits) and
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+
+# NOT IN
+select auto from t1 where
+string not in("aaaa","cccc") and
+vstring not in("aaaa","cccc") and
+bin not in(0xAAAA,0xCCCC) and
+vbin not in(0xAAAA,0xCCCC) and
+tiny not in(-1,-3) and
+short not in(-1,-3) and
+medium not in(-1,-3) and
+long_int not in(-1,-3) and
+longlong not in(-1,-3) and
+utiny not in(1,3) and
+ushort not in(1,3) and
+umedium not in(1,3) and
+ulong not in(1,3) and
+ulonglong not in(1,3) and
+bits not in(b'001',b'011') and
+options not in('one','three') and
+flags not in('one','one,two,three') and
+date_field not in('1901-01-01','1903-03-03') and
+year_field not in('1901','1903') and
+time_field not in('01:01:01','03:03:03') and
+date_time not in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+"aaaa" not in(string) and
+"aaaa" not in(vstring) and
+0xAAAA not in(bin) and
+0xAAAA not in(vbin) and
+(-1 not in(tiny)) and
+(-1 not in(short)) and
+(-1 not in(medium)) and
+(-1 not in(long_int)) and
+(-1 not in(longlong)) and
+1 not in(utiny) and
+1 not in(ushort) and
+1 not in(umedium) and
+1 not in(ulong) and
+1 not in(ulonglong) and
+b'001' not in(bits) and
+'one' not in(options) and
+'one' not in(flags) and
+'1901-01-01' not in(date_field) and
+'1901' not in(year_field) and
+'01:01:01' not in(time_field) and
+'1901-01-01 01:01:01' not in(date_time)
+order by auto;
+
# Various tests
select * from t2 where attr3 is null or attr1 > 2 and pk1= 3 order by pk1;
select * from t2 where attr3 is not null and attr1 > 2 order by pk1;
@@ -955,6 +1151,402 @@ bin not like concat(0xBB, '%') and
vbin not like concat(0xBB, '%')
order by auto;
+# BETWEEN
+explain
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+(string between "aaaa" and "cccc") and
+(vstring between "aaaa" and "cccc") and
+(bin between 0xAAAA and 0xCCCC) and
+(vbin between 0xAAAA and 0xCCCC) and
+(tiny between -3 and -1) and
+(short between -3 and -1) and
+(medium between -3 and -1) and
+(long_int between -3 and -1) and
+(longlong between -3 and -1) and
+(utiny between 1 and 3) and
+(ushort between 1 and 3) and
+(umedium between 1 and 3) and
+(ulong between 1 and 3) and
+(ulonglong between 1 and 3) and
+/* (bits between b'001' and b'011') and */
+(options between 'one' and 'three') and
+(flags between 'one' and 'one,two,three') and
+(date_field between '1901-01-01' and '1903-03-03') and
+(year_field between '1901' and '1903') and
+(time_field between '01:01:01' and '03:03:03') and
+(date_time between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+explain
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+
+select auto from t1 where
+("aaaa" between string and string) and
+("aaaa" between vstring and vstring) and
+(0xAAAA between bin and bin) and
+(0xAAAA between vbin and vbin) and
+(-1 between tiny and tiny) and
+(-1 between short and short) and
+(-1 between medium and medium) and
+(-1 between long_int and long_int) and
+(-1 between longlong and longlong) and
+(1 between utiny and utiny) and
+(1 between ushort and ushort) and
+(1 between umedium and umedium) and
+(1 between ulong and ulong) and
+(1 between ulonglong and ulonglong) and
+/* (b'001' between bits and bits) and */
+('one' between options and options) and
+('one' between flags and flags) and
+('1901-01-01' between date_field and date_field) and
+('1901' between year_field and year_field) and
+('01:01:01' between time_field and time_field) and
+('1901-01-01 01:01:01' between date_time and date_time)
+order by auto;
+
+# NOT BETWEEN
+explain
+select auto from t1 where
+(string not between "aaaa" and "cccc") and
+(vstring not between "aaaa" and "cccc") and
+(bin not between 0xAAAA and 0xCCCC) and
+(vbin not between 0xAAAA and 0xCCCC) and
+(tiny not between -3 and -1) and
+(short not between -3 and -1) and
+(medium not between -3 and -1) and
+(long_int not between -3 and -1) and
+(longlong not between -3 and -1) and
+(utiny not between 1 and 3) and
+(ushort not between 1 and 3) and
+(umedium not between 1 and 3) and
+(ulong not between 1 and 3) and
+(ulonglong not between 1 and 3) and
+/* (bits not between b'001' and b'011') and */
+(options not between 'one' and 'three') and
+(flags not between 'one' and 'one,two,three') and
+(date_field not between '1901-01-01' and '1903-03-03') and
+(year_field not between '1901' and '1903') and
+(time_field not between '01:01:01' and '03:03:03') and
+(date_time not between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+(string not between "aaaa" and "cccc") and
+(vstring not between "aaaa" and "cccc") and
+(bin not between 0xAAAA and 0xCCCC) and
+(vbin not between 0xAAAA and 0xCCCC) and
+(tiny not between -3 and -1) and
+(short not between -3 and -1) and
+(medium not between -3 and -1) and
+(long_int not between -3 and -1) and
+(longlong not between -3 and -1) and
+(utiny not between 1 and 3) and
+(ushort not between 1 and 3) and
+(umedium not between 1 and 3) and
+(ulong not between 1 and 3) and
+(ulonglong not between 1 and 3) and
+/* (bits not between b'001' and b'011') and */
+(options not between 'one' and 'three') and
+(flags not between 'one' and 'one,two,three') and
+(date_field not between '1901-01-01' and '1903-03-03') and
+(year_field not between '1901' and '1903') and
+(time_field not between '01:01:01' and '03:03:03') and
+(date_time not between '1901-01-01 01:01:01' and '1903-03-03 03:03:03')
+order by auto;
+
+explain
+select auto from t1 where
+("aaaa" not between string and string) and
+("aaaa" not between vstring and vstring) and
+(0xAAAA not between bin and bin) and
+(0xAAAA not between vbin and vbin) and
+(-1 not between tiny and tiny) and
+(-1 not between short and short) and
+(-1 not between medium and medium) and
+(-1 not between long_int and long_int) and
+(-1 not between longlong and longlong) and
+(1 not between utiny and utiny) and
+(1 not between ushort and ushort) and
+(1 not between umedium and umedium) and
+(1 not between ulong and ulong) and
+(1 not between ulonglong and ulonglong) and
+/* (b'001' not between bits and bits) and */
+('one' not between options and options) and
+('one' not between flags and flags) and
+('1901-01-01' not between date_field and date_field) and
+('1901' not between year_field and year_field) and
+('01:01:01' not between time_field and time_field) and
+('1901-01-01 01:01:01' not between date_time and date_time)
+order by auto;
+
+select auto from t1 where
+("aaaa" not between string and string) and
+("aaaa" not between vstring and vstring) and
+(0xAAAA not between bin and bin) and
+(0xAAAA not between vbin and vbin) and
+(-1 not between tiny and tiny) and
+(-1 not between short and short) and
+(-1 not between medium and medium) and
+(-1 not between long_int and long_int) and
+(-1 not between longlong and longlong) and
+(1 not between utiny and utiny) and
+(1 not between ushort and ushort) and
+(1 not between umedium and umedium) and
+(1 not between ulong and ulong) and
+(1 not between ulonglong and ulonglong) and
+/* (b'001' not between bits and bits) and */
+('one' not between options and options) and
+('one' not between flags and flags) and
+('1901-01-01' not between date_field and date_field) and
+('1901' not between year_field and year_field) and
+('01:01:01' not between time_field and time_field) and
+('1901-01-01 01:01:01' not between date_time and date_time)
+order by auto;
+
+# IN
+explain
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+string in("aaaa","cccc") and
+vstring in("aaaa","cccc") and
+bin in(0xAAAA,0xCCCC) and
+vbin in(0xAAAA,0xCCCC) and
+tiny in(-1,-3) and
+short in(-1,-3) and
+medium in(-1,-3) and
+long_int in(-1,-3) and
+longlong in(-1,-3) and
+utiny in(1,3) and
+ushort in(1,3) and
+umedium in(1,3) and
+ulong in(1,3) and
+ulonglong in(1,3) and
+/* bits in(b'001',b'011') and */
+options in('one','three') and
+flags in('one','one,two,three') and
+date_field in('1901-01-01','1903-03-03') and
+year_field in('1901','1903') and
+time_field in('01:01:01','03:03:03') and
+date_time in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+explain
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+(-1 in(tiny)) and
+(-1 in (short)) and
+(-1 in(medium)) and
+(-1 in(long_int)) and
+(-1 in(longlong)) and
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+
+select auto from t1 where
+"aaaa" in(string) and
+"aaaa" in(vstring) and
+0xAAAA in(bin) and
+0xAAAA in(vbin) and
+(-1 in(tiny)) and
+(-1 in (short)) and
+(-1 in(medium)) and
+(-1 in(long_int)) and
+(-1 in(longlong)) and
+1 in(utiny) and
+1 in(ushort) and
+1 in(umedium) and
+1 in(ulong) and
+1 in(ulonglong) and
+/* b'001' in(bits) and */
+'one' in(options) and
+'one' in(flags) and
+'1901-01-01' in(date_field) and
+'1901' in(year_field) and
+'01:01:01' in(time_field) and
+'1901-01-01 01:01:01' in(date_time)
+order by auto;
+
+# NOT IN
+explain
+select auto from t1 where
+string not in("aaaa","cccc") and
+vstring not in("aaaa","cccc") and
+bin not in(0xAAAA,0xCCCC) and
+vbin not in(0xAAAA,0xCCCC) and
+tiny not in(-1,-3) and
+short not in(-1,-3) and
+medium not in(-1,-3) and
+long_int not in(-1,-3) and
+longlong not in(-1,-3) and
+utiny not in(1,3) and
+ushort not in(1,3) and
+umedium not in(1,3) and
+ulong not in(1,3) and
+ulonglong not in(1,3) and
+/* bits not in(b'001',b'011') and */
+options not in('one','three') and
+flags not in('one','one,two,three') and
+date_field not in('1901-01-01','1903-03-03') and
+year_field not in('1901','1903') and
+time_field not in('01:01:01','03:03:03') and
+date_time not in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+select auto from t1 where
+string not in("aaaa","cccc") and
+vstring not in("aaaa","cccc") and
+bin not in(0xAAAA,0xCCCC) and
+vbin not in(0xAAAA,0xCCCC) and
+tiny not in(-1,-3) and
+short not in(-1,-3) and
+medium not in(-1,-3) and
+long_int not in(-1,-3) and
+longlong not in(-1,-3) and
+utiny not in(1,3) and
+ushort not in(1,3) and
+umedium not in(1,3) and
+ulong not in(1,3) and
+ulonglong not in(1,3) and
+/* bits not in(b'001',b'011') and */
+options not in('one','three') and
+flags not in('one','one,two,three') and
+date_field not in('1901-01-01','1903-03-03') and
+year_field not in('1901','1903') and
+time_field not in('01:01:01','03:03:03') and
+date_time not in('1901-01-01 01:01:01','1903-03-03 03:03:03')
+order by auto;
+
+explain
+select auto from t1 where
+"aaaa" not in(string) and
+"aaaa" not in(vstring) and
+0xAAAA not in(bin) and
+0xAAAA not in(vbin) and
+(-1 not in(tiny)) and
+(-1 not in(short)) and
+(-1 not in(medium)) and
+(-1 not in(long_int)) and
+(-1 not in(longlong)) and
+1 not in(utiny) and
+1 not in(ushort) and
+1 not in(umedium) and
+1 not in(ulong) and
+1 not in(ulonglong) and
+/* b'001' not in(bits) and */
+'one' not in(options) and
+'one' not in(flags) and
+'1901-01-01' not in(date_field) and
+'1901' not in(year_field) and
+'01:01:01' not in(time_field) and
+'1901-01-01 01:01:01' not in(date_time)
+order by auto;
+
+select auto from t1 where
+"aaaa" not in(string) and
+"aaaa" not in(vstring) and
+0xAAAA not in(bin) and
+0xAAAA not in(vbin) and
+(-1 not in(tiny)) and
+(-1 not in(short)) and
+(-1 not in(medium)) and
+(-1 not in(long_int)) and
+(-1 not in(longlong)) and
+1 not in(utiny) and
+1 not in(ushort) and
+1 not in(umedium) and
+1 not in(ulong) and
+1 not in(ulonglong) and
+/* b'001' not in(bits) and */
+'one' not in(options) and
+'one' not in(flags) and
+'1901-01-01' not in(date_field) and
+'1901' not in(year_field) and
+'01:01:01' not in(time_field) and
+'1901-01-01 01:01:01' not in(date_time)
+order by auto;
+
# Update test
update t1
set medium = 17
@@ -1044,6 +1636,8 @@ explain
select auto from t1 where string = "aaaa" collate latin1_general_ci order by auto;
explain
select * from t2 where (attr1 < 2) = (attr2 < 2) order by pk1;
+explain
+select * from t3 left join t4 on t4.attr2 = t3.attr2 where t4.attr1 > 1 and t4.attr3 < 5 or t4.attr1 is null order by t4.pk1;
set engine_condition_pushdown = @old_ecpd;
DROP TABLE t1,t2,t3,t4;
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 9e8a7a1b56f..f8d833b6b73 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -130,6 +130,13 @@ set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%';
+#
+# Bug #10904 Illegal mix of collations between
+# a system variable and a constant
+#
+SELECT @@version LIKE 'non-existent';
+SELECT @@version_compile_os LIKE 'non-existent';
+
# The following should give errors
--error 1231
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 2308536cd37..feb9c77a5b9 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -184,10 +184,18 @@ static void test_key_cache(KEY_CACHE *keycache,
static FILE *keycache_debug_log=NULL;
static void keycache_debug_print _VARARGS((const char *fmt,...));
#define KEYCACHE_DEBUG_OPEN \
- if (!keycache_debug_log) keycache_debug_log=fopen(KEYCACHE_DEBUG_LOG, "w")
+ if (!keycache_debug_log) \
+ { \
+ keycache_debug_log= fopen(KEYCACHE_DEBUG_LOG, "w"); \
+ (void) setvbuf(keycache_debug_log, NULL, _IOLBF, BUFSIZ); \
+ }
#define KEYCACHE_DEBUG_CLOSE \
- if (keycache_debug_log) { fclose(keycache_debug_log); keycache_debug_log=0; }
+ if (keycache_debug_log) \
+ { \
+ fclose(keycache_debug_log); \
+ keycache_debug_log= 0; \
+ }
#else
#define KEYCACHE_DEBUG_OPEN
#define KEYCACHE_DEBUG_CLOSE
@@ -213,7 +221,7 @@ static long keycache_thread_id;
#define KEYCACHE_THREAD_TRACE_BEGIN(l) \
{ struct st_my_thread_var *thread_var= my_thread_var; \
- keycache_thread_id= my_thread_var->id; \
+ keycache_thread_id= thread_var->id; \
KEYCACHE_DBUG_PRINT(l,("[thread %ld",keycache_thread_id)) }
#define KEYCACHE_THREAD_TRACE_END(l) \
@@ -240,12 +248,10 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond,
static int keycache_pthread_mutex_lock(pthread_mutex_t *mutex);
static void keycache_pthread_mutex_unlock(pthread_mutex_t *mutex);
static int keycache_pthread_cond_signal(pthread_cond_t *cond);
-static int keycache_pthread_cond_broadcast(pthread_cond_t *cond);
#else
#define keycache_pthread_mutex_lock pthread_mutex_lock
#define keycache_pthread_mutex_unlock pthread_mutex_unlock
#define keycache_pthread_cond_signal pthread_cond_signal
-#define keycache_pthread_cond_broadcast pthread_cond_broadcast
#endif /* defined(KEYCACHE_DEBUG) */
static uint next_power(uint value)
@@ -508,6 +514,8 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
keycache->can_be_used= 0;
while (keycache->cnt_for_resize_op)
{
+ KEYCACHE_DBUG_PRINT("resize_key_cache: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
}
@@ -520,7 +528,11 @@ finish:
unlink_from_queue(wqueue, thread);
/* Signal for the next resize request to proceeed if any */
if (wqueue->last_thread)
+ {
+ KEYCACHE_DBUG_PRINT("resize_key_cache: signal",
+ ("thread %ld", wqueue->last_thread->next->id));
keycache_pthread_cond_signal(&wqueue->last_thread->next->suspend);
+ }
keycache_pthread_mutex_unlock(&keycache->cache_lock);
return blocks;
}
@@ -544,7 +556,11 @@ static inline void dec_counter_for_resize_op(KEY_CACHE *keycache)
struct st_my_thread_var *last_thread;
if (!--keycache->cnt_for_resize_op &&
(last_thread= keycache->resize_queue.last_thread))
+ {
+ KEYCACHE_DBUG_PRINT("dec_counter_for_resize_op: signal",
+ ("thread %ld", last_thread->next->id));
keycache_pthread_cond_signal(&last_thread->next->suspend);
+ }
}
/*
@@ -761,8 +777,8 @@ static void release_queue(KEYCACHE_WQUEUE *wqueue)
do
{
thread=next;
- keycache_pthread_cond_signal(&thread->suspend);
KEYCACHE_DBUG_PRINT("release_queue: signal", ("thread %ld", thread->id));
+ keycache_pthread_cond_signal(&thread->suspend);
next=thread->next;
thread->next= NULL;
}
@@ -876,7 +892,8 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
BLOCK_LINK **pins;
KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests));
- if (!hot && keycache->waiting_for_block.last_thread) {
+ if (!hot && keycache->waiting_for_block.last_thread)
+ {
/* Signal that in the LRU warm sub-chain an available block has appeared */
struct st_my_thread_var *last_thread=
keycache->waiting_for_block.last_thread;
@@ -894,6 +911,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
*/
if ((HASH_LINK *) thread->opt_info == hash_link)
{
+ KEYCACHE_DBUG_PRINT("link_block: signal", ("thread %ld", thread->id));
keycache_pthread_cond_signal(&thread->suspend);
unlink_from_queue(&keycache->waiting_for_block, thread);
block->requests++;
@@ -1000,11 +1018,10 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count)
linking it to the LRU chain if it's the last request
SYNOPSIS
-
- unreg_block()
- keycache pointer to a key cache data structure
- block pointer to the block to link to the LRU chain
- at_end <-> to link the block at the end of the LRU chain
+ unreg_request()
+ keycache pointer to a key cache data structure
+ block pointer to the block to link to the LRU chain
+ at_end <-> to link the block at the end of the LRU chain
RETURN VALUE
none
@@ -1086,6 +1103,9 @@ static inline void wait_for_readers(KEY_CACHE *keycache, BLOCK_LINK *block)
struct st_my_thread_var *thread= my_thread_var;
while (block->hash_link->requests)
{
+ KEYCACHE_DBUG_PRINT("wait_for_readers: wait",
+ ("suspend thread %ld block %u",
+ thread->id, BLOCK_NUMBER(block)));
block->condvar= &thread->suspend;
keycache_pthread_cond_wait(&thread->suspend, &keycache->cache_lock);
block->condvar= NULL;
@@ -1143,6 +1163,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
*/
if (page->file == hash_link->file && page->filepos == hash_link->diskpos)
{
+ KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id));
keycache_pthread_cond_signal(&thread->suspend);
unlink_from_queue(&keycache->waiting_for_hash_link, thread);
}
@@ -1225,6 +1246,8 @@ restart:
page.filepos= filepos;
thread->opt_info= (void *) &page;
link_into_queue(&keycache->waiting_for_hash_link, thread);
+ KEYCACHE_DBUG_PRINT("get_hash_link: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
thread->opt_info= NULL;
@@ -1343,6 +1366,8 @@ restart:
add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
{
+ KEYCACHE_DBUG_PRINT("find_key_block: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
}
@@ -1360,7 +1385,9 @@ restart:
/* This is a request for a page to be removed from cache */
KEYCACHE_DBUG_PRINT("find_key_block",
- ("request for old page in block %u",BLOCK_NUMBER(block)));
+ ("request for old page in block %u "
+ "wrmode: %d block->status: %d",
+ BLOCK_NUMBER(block), wrmode, block->status));
/*
Only reading requests can proceed until the old dirty page is flushed,
all others are to be suspended, then resubmitted
@@ -1379,6 +1406,8 @@ restart:
/* Wait until the request can be resubmitted */
do
{
+ KEYCACHE_DBUG_PRINT("find_key_block: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
}
@@ -1448,6 +1477,8 @@ restart:
link_into_queue(&keycache->waiting_for_block, thread);
do
{
+ KEYCACHE_DBUG_PRINT("find_key_block: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
}
@@ -1528,9 +1559,13 @@ restart:
else
{
/* This is for secondary requests for a new page only */
- page_status= block->hash_link == hash_link &&
- (block->status & BLOCK_READ) ?
- PAGE_READ : PAGE_WAIT_TO_BE_READ;
+ KEYCACHE_DBUG_PRINT("find_key_block",
+ ("block->hash_link: %p hash_link: %p "
+ "block->status: %u", block->hash_link,
+ hash_link, block->status ));
+ page_status= (((block->hash_link == hash_link) &&
+ (block->status & BLOCK_READ)) ?
+ PAGE_READ : PAGE_WAIT_TO_BE_READ);
}
}
keycache->global_cache_read++;
@@ -1538,17 +1573,22 @@ restart:
else
{
reg_requests(keycache, block, 1);
- page_status = block->hash_link == hash_link &&
- (block->status & BLOCK_READ) ?
- PAGE_READ : PAGE_WAIT_TO_BE_READ;
+ KEYCACHE_DBUG_PRINT("find_key_block",
+ ("block->hash_link: %p hash_link: %p "
+ "block->status: %u", block->hash_link,
+ hash_link, block->status ));
+ page_status= (((block->hash_link == hash_link) &&
+ (block->status & BLOCK_READ)) ?
+ PAGE_READ : PAGE_WAIT_TO_BE_READ);
}
}
KEYCACHE_DBUG_ASSERT(page_status != -1);
*page_st=page_status;
KEYCACHE_DBUG_PRINT("find_key_block",
- ("fd: %u pos %lu page_status %lu",
- (uint) file,(ulong) filepos,(uint) page_status));
+ ("fd: %u pos %lu block->status %u page_status %lu",
+ (uint) file, (ulong) filepos, block->status,
+ (uint) page_status));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",
@@ -1604,6 +1644,10 @@ static void read_block(KEY_CACHE *keycache,
/* Page is not in buffer yet, is to be read from disk */
keycache_pthread_mutex_unlock(&keycache->cache_lock);
+ /*
+ Here other threads may step in and register as secondary readers.
+ They will register in block->wqueue[COND_FOR_REQUESTED].
+ */
got_length= my_pread(block->hash_link->file, block->buffer,
read_length, block->hash_link->diskpos, MYF(0));
keycache_pthread_mutex_lock(&keycache->cache_lock);
@@ -1634,6 +1678,8 @@ static void read_block(KEY_CACHE *keycache,
add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread);
do
{
+ KEYCACHE_DBUG_PRINT("read_block: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
}
@@ -1855,6 +1901,10 @@ int key_cache_insert(KEY_CACHE *keycache,
/* The requested page is to be read into the block buffer */
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_unlock(&keycache->cache_lock);
+ /*
+ Here other threads may step in and register as secondary readers.
+ They will register in block->wqueue[COND_FOR_REQUESTED].
+ */
#endif
/* Copy data from buff */
@@ -1865,9 +1915,15 @@ int key_cache_insert(KEY_CACHE *keycache,
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock(&keycache->cache_lock);
+ /* Here we are alone again. */
#endif
block->status= BLOCK_READ;
block->length= read_length+offset;
+ KEYCACHE_DBUG_PRINT("key_cache_insert",
+ ("primary request: new page in cache"));
+ /* Signal that all pending requests for this now can be processed. */
+ if (block->wqueue[COND_FOR_REQUESTED].last_thread)
+ release_queue(&block->wqueue[COND_FOR_REQUESTED]);
}
remove_reader(block);
@@ -2074,9 +2130,16 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
{
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
- ("block %u to be freed",BLOCK_NUMBER(block)));
+ ("block %u to be freed, hash_link %p",
+ BLOCK_NUMBER(block), block->hash_link));
if (block->hash_link)
{
+ /*
+ While waiting for readers to finish, new readers might request the
+ block. But since we set block->status|= BLOCK_REASSIGNED, they
+ will wait on block->wqueue[COND_FOR_SAVED]. They must be signalled
+ later.
+ */
block->status|= BLOCK_REASSIGNED;
wait_for_readers(keycache, block);
unlink_hash(keycache, block->hash_link);
@@ -2102,6 +2165,10 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
keycache->free_block_list= block;
/* Keep track of the number of currently unused blocks. */
keycache->blocks_unused++;
+
+ /* All pending requests for this page must be resubmitted. */
+ if (block->wqueue[COND_FOR_SAVED].last_thread)
+ release_queue(&block->wqueue[COND_FOR_SAVED]);
}
@@ -2334,6 +2401,8 @@ restart:
add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
{
+ KEYCACHE_DBUG_PRINT("flush_key_blocks_int: wait",
+ ("suspend thread %ld", thread->id));
keycache_pthread_cond_wait(&thread->suspend,
&keycache->cache_lock);
}
@@ -2685,14 +2754,6 @@ static int keycache_pthread_cond_signal(pthread_cond_t *cond)
}
-static int keycache_pthread_cond_broadcast(pthread_cond_t *cond)
-{
- int rc;
- KEYCACHE_THREAD_TRACE("signal");
- rc= pthread_cond_broadcast(cond);
- return rc;
-}
-
#if defined(KEYCACHE_DEBUG_LOG)
diff --git a/sql/field.cc b/sql/field.cc
index ed9d3e1ecd9..08a785b2780 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5859,31 +5859,32 @@ int Field_str::store(double nr)
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
uint length;
bool use_scientific_notation= TRUE;
+ uint char_length= field_length / charset()->mbmaxlen;
/*
Check fabs(nr) against longest value that can be stored in field,
which depends on whether the value is < 1 or not, and negative or not
*/
double anr= fabs(nr);
int neg= (nr < 0.0) ? 1 : 0;
- if (field_length > 4 && field_length < 32 &&
- (anr < 1.0 ? anr > 1/(log_10[max(0,(int) field_length-neg-2)]) /* -2 for "0." */
- : anr < log_10[field_length-neg]-1))
+ if (char_length > 4 && char_length < 32 &&
+ (anr < 1.0 ? anr > 1/(log_10[max(0,(int) char_length-neg-2)]) /* -2 for "0." */
+ : anr < log_10[char_length-neg]-1))
use_scientific_notation= FALSE;
length= (uint) my_sprintf(buff, (buff, "%-.*g",
(use_scientific_notation ?
- max(0, (int)field_length-neg-5) :
- field_length),
+ max(0, (int)char_length-neg-5) :
+ char_length),
nr));
/*
+1 below is because "precision" in %g above means the
max. number of significant digits, not the output width.
Thus the width can be larger than number of significant digits by 1
(for decimal point)
- the test for field_length < 5 is for extreme cases,
+ the test for char_length < 5 is for extreme cases,
like inserting 500.0 in char(1)
*/
- DBUG_ASSERT(field_length < 5 || length <= field_length+1);
+ DBUG_ASSERT(char_length < 5 || length <= char_length+1);
return store((const char *) buff, length, charset());
}
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 5f4027c1a88..d2652b242ce 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -5964,11 +5964,14 @@ ha_innobase::external_lock(
TABLES if AUTOCOMMIT=1. It does not make much sense to acquire
an InnoDB table lock if it is released immediately at the end
of LOCK TABLES, and InnoDB's table locks in that case cause
- VERY easily deadlocks. */
+ VERY easily deadlocks. We do not set InnoDB table locks when
+ MySQL sets them at the start of a stored procedure call
+ (MySQL does have thd->in_lock_tables TRUE there). */
if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd->in_lock_tables &&
+ thd->lex->sql_command != SQLCOM_CALL &&
thd->variables.innodb_table_locks &&
(thd->options & OPTION_NOT_AUTOCOMMIT)) {
@@ -6479,11 +6482,21 @@ ha_innobase::store_lock(
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
+ /* Starting from 5.0.7, we weaken also the table locks
+ set at the start of a MySQL stored procedure call, just like
+ we weaken the locks set at the start of an SQL statement.
+ MySQL does set thd->in_lock_tables TRUE there, but in reality
+ we do not need table locks to make the execution of a
+ single transaction stored procedure call deterministic
+ (if it does not use a consistent read). */
+
/* If we are not doing a LOCK TABLE or DISCARD/IMPORT
TABLESPACE or TRUNCATE TABLE, then allow multiple writers */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
- lock_type <= TL_WRITE) && !thd->in_lock_tables
+ lock_type <= TL_WRITE)
+ && (!thd->in_lock_tables
+ || thd->lex->sql_command == SQLCOM_CALL)
&& !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
@@ -6497,7 +6510,10 @@ ha_innobase::store_lock(
to t2. Convert the lock to a normal read lock to allow
concurrent inserts to t2. */
- if (lock_type == TL_READ_NO_INSERT && !thd->in_lock_tables) {
+ if (lock_type == TL_READ_NO_INSERT
+ && (!thd->in_lock_tables
+ || thd->lex->sql_command == SQLCOM_CALL)) {
+
lock_type = TL_READ;
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index fc21a634b00..2bd0e992ae4 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -6077,572 +6077,778 @@ void ndb_serialize_cond(const Item *item, void *arg)
context->supported= FALSE;
break;
}
-
+
DBUG_VOID_RETURN;
}
if (context->supported)
{
- Ndb_cond_stack *ndb_stack= context->stack_ptr;
- Ndb_cond *prev_cond= context->cond_ptr;
- Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
- if (!ndb_stack->ndb_cond)
- ndb_stack->ndb_cond= curr_cond;
- curr_cond->prev= prev_cond;
- if (prev_cond) prev_cond->next= curr_cond;
-
- // Check for end of AND/OR expression
- if (!item)
+ Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
+ const Item_func *func_item;
+ // Check if we are rewriting some unsupported function call
+ if (rewrite_context &&
+ (func_item= rewrite_context->func_item) &&
+ rewrite_context->count++ == 0)
{
- // End marker for condition group
- DBUG_PRINT("info", ("End of condition group"));
- curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
- }
- else
- switch(item->type()) {
- case(Item::FIELD_ITEM): {
- Item_field *field_item= (Item_field *) item;
- Field *field= field_item->field;
- enum_field_types type= field->type();
+ switch(func_item->functype()) {
+ case(Item_func::BETWEEN):
/*
- Check that the field is part of the table of the handler
- instance and that we expect a field with of this result type.
+ Rewrite
+ <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
+ to <field>|<const> > <const1>|<field1> AND
+ <field>|<const> < <const2>|<field2>
+ or actually in prefix format
+ BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
+ LT(<field>|<const>, <const2>|<field2>), END()
*/
- if (context->table == field->table)
- {
- const NDBTAB *tab= (const NDBTAB *) context->ndb_table;
- DBUG_PRINT("info", ("FIELD_ITEM"));
- DBUG_PRINT("info", ("table %s", tab->getName()));
- DBUG_PRINT("info", ("column %s", field->field_name));
- DBUG_PRINT("info", ("result type %d", field->result_type()));
-
- // Check that we are expecting a field and with the correct
- // result type
- if(context->expecting(Item::FIELD_ITEM) &&
- (context->expecting_field_result(field->result_type()) ||
- // Date and year can be written as strings
- (type == MYSQL_TYPE_TIME ||
- type == MYSQL_TYPE_DATE ||
- type == MYSQL_TYPE_YEAR ||
- type == MYSQL_TYPE_DATETIME)
- ? context->expecting_field_result(STRING_RESULT) : true)
- // Bit fields no yet supported in scan filter
- && type != MYSQL_TYPE_BIT)
+ case(Item_func::IN_FUNC): {
+ /*
+ Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
+ to <field>|<const> = <const1>|<field1> OR
+ <field> = <const2>|<field2> ...
+ or actually in prefix format
+ BEGIN(OR) EQ(<field>|<const>, <const1><field1>),
+ EQ(<field>|<const>, <const2>|<field2>), ... END()
+ Each part of the disjunction is added for each call
+ to ndb_serialize_cond and end of rewrite statement
+ is wrapped in end of ndb_serialize_cond
+ */
+ if (context->expecting(item->type()))
+ {
+ // This is the <field>|<const> item, save it in the rewrite context
+ rewrite_context->left_hand_item= item;
+ if (item->type() == Item::FUNC_ITEM)
{
- const NDBCOL *col= tab->getColumn(field->field_name);
- DBUG_ASSERT(col);
- curr_cond->ndb_item= new Ndb_item(field, col->getColumnNo());
- context->dont_expect(Item::FIELD_ITEM);
- context->expect_no_field_result();
- if (context->expect_mask)
+ Item_func *func_item= (Item_func *) item;
+ if (func_item->functype() == Item_func::UNKNOWN_FUNC &&
+ func_item->const_item())
{
- // We have not seen second argument yet
- if (type == MYSQL_TYPE_TIME ||
- type == MYSQL_TYPE_DATE ||
- type == MYSQL_TYPE_YEAR ||
- type == MYSQL_TYPE_DATETIME)
- {
- context->expect_only(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- }
- else
- switch(field->result_type()) {
- case(STRING_RESULT):
- // Expect char string or binary string
- context->expect_only(Item::STRING_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect_collation(field_item->collation.collation);
- break;
- case(REAL_RESULT):
- context->expect_only(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- break;
- case(INT_RESULT):
- context->expect_only(Item::INT_ITEM);
- context->expect(Item::VARBIN_ITEM);
- break;
- case(DECIMAL_RESULT):
- context->expect_only(Item::DECIMAL_ITEM);
- context->expect(Item::REAL_ITEM);
- break;
- default:
- break;
- }
+ // Skip any arguments since we will evaluate function instead
+ DBUG_PRINT("info", ("Skip until end of arguments marker"));
+ context->skip= func_item->argument_count();
}
else
{
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- // Check that field and string constant collations are the same
- if ((field->result_type() == STRING_RESULT) &&
- !context->expecting_collation(item->collation.collation))
- {
- DBUG_PRINT("info", ("Found non-matching collation %s",
- item->collation.collation->name));
- context->supported= FALSE;
- }
+ DBUG_PRINT("info", ("Found unsupported functional expression in BETWEEN|IN"));
+ context->supported= FALSE;
+ DBUG_VOID_RETURN;
+
}
- break;
}
}
- DBUG_PRINT("info", ("Was not expecting field of type %u",
- field->result_type()));
- context->supported= FALSE;
- break;
- }
- case(Item::FUNC_ITEM): {
- Item_func *func_item= (Item_func *) item;
- // Check that we expect a function or functional expression here
- if (context->expecting(Item::FUNC_ITEM) ||
- func_item->functype() == Item_func::UNKNOWN_FUNC)
- context->expect_nothing();
else
{
- // Did not expect function here
+ // Non-supported BETWEEN|IN expression
+ DBUG_PRINT("info", ("Found unexpected item of type %u in BETWEEN|IN",
+ item->type()));
context->supported= FALSE;
- break;
+ DBUG_VOID_RETURN;
}
-
+ break;
+ }
+ default:
+ context->supported= FALSE;
+ break;
+ }
+ DBUG_VOID_RETURN;
+ }
+ else
+ {
+ Ndb_cond_stack *ndb_stack= context->stack_ptr;
+ Ndb_cond *prev_cond= context->cond_ptr;
+ Ndb_cond *curr_cond= context->cond_ptr= new Ndb_cond();
+ if (!ndb_stack->ndb_cond)
+ ndb_stack->ndb_cond= curr_cond;
+ curr_cond->prev= prev_cond;
+ if (prev_cond) prev_cond->next= curr_cond;
+ // Check if we are rewriting some unsupported function call
+ if (context->rewrite_stack)
+ {
+ Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
+ const Item_func *func_item= rewrite_context->func_item;
switch(func_item->functype()) {
- case(Item_func::EQ_FUNC): {
- DBUG_PRINT("info", ("EQ_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::NE_FUNC): {
- DBUG_PRINT("info", ("NE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::LT_FUNC): {
- DBUG_PRINT("info", ("LT_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::LE_FUNC): {
- DBUG_PRINT("info", ("LE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::GE_FUNC): {
- DBUG_PRINT("info", ("GE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::GT_FUNC): {
- DBUG_PRINT("info", ("GT_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::REAL_ITEM);
- context->expect(Item::DECIMAL_ITEM);
- context->expect(Item::INT_ITEM);
- context->expect(Item::VARBIN_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
- break;
- }
- case(Item_func::LIKE_FUNC): {
- DBUG_PRINT("info", ("LIKE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- break;
- }
- case(Item_func::NOTLIKE_FUNC): {
- DBUG_PRINT("info", ("NOTLIKE_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::STRING_ITEM);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- break;
- }
- case(Item_func::ISNULL_FUNC): {
- DBUG_PRINT("info", ("ISNULL_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
+ case(Item_func::BETWEEN): {
+ /*
+ Rewrite
+ <field>|<const> BETWEEN <const1>|<field1> AND <const2>|<field2>
+ to <field>|<const> > <const1>|<field1> AND
+ <field>|<const> < <const2>|<field2>
+ or actually in prefix format
+ BEGIN(AND) GT(<field>|<const>, <const1>|<field1>),
+ LT(<field>|<const>, <const2>|<field2>), END()
+ */
+ if (rewrite_context->count == 2)
+ {
+ // Lower limit of BETWEEN
+ DBUG_PRINT("info", ("GE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::GE_FUNC, 2);
+ }
+ else if (rewrite_context->count == 3)
+ {
+ // Upper limit of BETWEEN
+ DBUG_PRINT("info", ("LE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::LE_FUNC, 2);
+ }
+ else
+ {
+ // Illegal BETWEEN expression
+ DBUG_PRINT("info", ("Illegal BETWEEN expression"));
+ context->supported= FALSE;
+ DBUG_VOID_RETURN;
+ }
break;
}
- case(Item_func::ISNOTNULL_FUNC): {
- DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::FIELD_ITEM);
- context->expect_field_result(STRING_RESULT);
- context->expect_field_result(REAL_RESULT);
- context->expect_field_result(INT_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
+ case(Item_func::IN_FUNC): {
+ /*
+ Rewrite <field>|<const> IN(<const1>|<field1>, <const2>|<field2>,..)
+ to <field>|<const> = <const1>|<field1> OR
+ <field> = <const2>|<field2> ...
+ or actually in prefix format
+ BEGIN(OR) EQ(<field>|<const>, <const1><field1>),
+ EQ(<field>|<const>, <const2>|<field2>), ... END()
+ Each part of the disjunction is added for each call
+ to ndb_serialize_cond and end of rewrite statement
+ is wrapped in end of ndb_serialize_cond
+ */
+ DBUG_PRINT("info", ("EQ_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::EQ_FUNC, 2);
break;
}
- case(Item_func::NOT_FUNC): {
- DBUG_PRINT("info", ("NOT_FUNC"));
- curr_cond->ndb_item= new Ndb_item(func_item->functype(),
- func_item);
- context->expect(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- break;
+ default:
+ context->supported= FALSE;
}
- case(Item_func::UNKNOWN_FUNC): {
- DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
- func_item->const_item()?"const":""));
- DBUG_PRINT("info", ("result type %d", func_item->result_type()));
- if (func_item->const_item())
- switch(func_item->result_type()) {
- case(STRING_RESULT): {
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::STRING_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ // Handle left hand <field>|<const>
+ context->rewrite_stack= NULL; // Disable rewrite mode
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FUNC_ITEM);
+ ndb_serialize_cond(rewrite_context->left_hand_item, arg);
+ context->skip= 0; // Any FUNC_ITEM expression has already been parsed
+ context->rewrite_stack= rewrite_context; // Enable rewrite mode
+ if (!context->supported)
+ DBUG_VOID_RETURN;
+
+ prev_cond= context->cond_ptr;
+ curr_cond= context->cond_ptr= new Ndb_cond();
+ prev_cond->next= curr_cond;
+ }
+
+ // Check for end of AND/OR expression
+ if (!item)
+ {
+ // End marker for condition group
+ DBUG_PRINT("info", ("End of condition group"));
+ curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
+ }
+ else
+ switch(item->type()) {
+ case(Item::FIELD_ITEM): {
+ Item_field *field_item= (Item_field *) item;
+ Field *field= field_item->field;
+ enum_field_types type= field->type();
+ /*
+ Check that the field is part of the table of the handler
+ instance and that we expect a field with of this result type.
+ */
+ if (context->table == field->table)
+ {
+ const NDBTAB *tab= (const NDBTAB *) context->ndb_table;
+ DBUG_PRINT("info", ("FIELD_ITEM"));
+ DBUG_PRINT("info", ("table %s", tab->getName()));
+ DBUG_PRINT("info", ("column %s", field->field_name));
+ DBUG_PRINT("info", ("result type %d", field->result_type()));
+
+ // Check that we are expecting a field and with the correct
+ // result type
+ if (context->expecting(Item::FIELD_ITEM) &&
+ (context->expecting_field_result(field->result_type()) ||
+ // Date and year can be written as strings
+ ((type == MYSQL_TYPE_TIME ||
+ type == MYSQL_TYPE_DATE ||
+ type == MYSQL_TYPE_YEAR ||
+ type == MYSQL_TYPE_DATETIME)
+ ? context->expecting_field_result(STRING_RESULT) : true)) &&
+ // Bit fields no yet supported in scan filter
+ type != MYSQL_TYPE_BIT)
+ {
+ const NDBCOL *col= tab->getColumn(field->field_name);
+ DBUG_ASSERT(col);
+ curr_cond->ndb_item= new Ndb_item(field, col->getColumnNo());
+ context->dont_expect(Item::FIELD_ITEM);
+ context->expect_no_field_result();
+ if (context->expect_mask)
{
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(STRING_RESULT);
- context->expect_collation(func_item->collation.collation);
+ // We have not seen second argument yet
+ if (type == MYSQL_TYPE_TIME ||
+ type == MYSQL_TYPE_DATE ||
+ type == MYSQL_TYPE_YEAR ||
+ type == MYSQL_TYPE_DATETIME)
+ {
+ context->expect_only(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ }
+ else
+ switch(field->result_type()) {
+ case(STRING_RESULT):
+ // Expect char string or binary string
+ context->expect_only(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect_collation(field_item->collation.collation);
+ break;
+ case(REAL_RESULT):
+ context->expect_only(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ break;
+ case(INT_RESULT):
+ context->expect_only(Item::INT_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ break;
+ case(DECIMAL_RESULT):
+ context->expect_only(Item::DECIMAL_ITEM);
+ context->expect(Item::REAL_ITEM);
+ break;
+ default:
+ break;
+ }
}
else
{
// Expect another logical expression
context->expect_only(Item::FUNC_ITEM);
context->expect(Item::COND_ITEM);
- // Check that string result have correct collation
- if (!context->expecting_collation(item->collation.collation))
+ // Check that field and string constant collations are the same
+ if ((field->result_type() == STRING_RESULT) &&
+ !context->expecting_collation(item->collation.collation)
+ && type != MYSQL_TYPE_TIME
+ && type != MYSQL_TYPE_DATE
+ && type != MYSQL_TYPE_YEAR
+ && type != MYSQL_TYPE_DATETIME)
{
DBUG_PRINT("info", ("Found non-matching collation %s",
- item->collation.collation->name));
- context->supported= FALSE;
+ item->collation.collation->name));
+ context->supported= FALSE;
}
}
- // Skip any arguments since we will evaluate function instead
- DBUG_PRINT("info", ("Skip until end of arguments marker"));
- context->skip= func_item->argument_count();
- break;
- }
- case(REAL_RESULT): {
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::REAL_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(REAL_RESULT);
- }
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- }
-
- // Skip any arguments since we will evaluate function instead
- DBUG_PRINT("info", ("Skip until end of arguments marker"));
- context->skip= func_item->argument_count();
break;
}
- case(INT_RESULT): {
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::INT_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(INT_RESULT);
- }
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- }
-
- // Skip any arguments since we will evaluate function instead
- DBUG_PRINT("info", ("Skip until end of arguments marker"));
- context->skip= func_item->argument_count();
- break;
- }
- case(DECIMAL_RESULT): {
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::DECIMAL_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(DECIMAL_RESULT);
- }
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- }
- // Skip any arguments since we will evaluate function instead
- DBUG_PRINT("info", ("Skip until end of arguments marker"));
- context->skip= func_item->argument_count();
- break;
- }
- default:
- break;
+ else
+ {
+ DBUG_PRINT("info", ("Was not expecting field of type %u",
+ field->result_type()));
+ context->supported= FALSE;
}
+ }
else
- // Function does not return constant expression
+ {
+ DBUG_PRINT("info", ("Was not expecting field from table %s(%s)",
+ context->table->s->table_name,
+ field->table->s->table_name));
context->supported= FALSE;
+ }
break;
}
- default: {
- DBUG_PRINT("info", ("Found func_item of type %d",
- func_item->functype()));
- context->supported= FALSE;
- }
- }
- break;
- }
- case(Item::STRING_ITEM):
- DBUG_PRINT("info", ("STRING_ITEM"));
- if (context->expecting(Item::STRING_ITEM))
- {
-#ifndef DBUG_OFF
- char buff[256];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- str.length(0);
- Item_string *string_item= (Item_string *) item;
- DBUG_PRINT("info", ("value \"%s\"",
- string_item->val_str(&str)->ptr()));
-#endif
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::STRING_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ case(Item::FUNC_ITEM): {
+ Item_func *func_item= (Item_func *) item;
+ // Check that we expect a function or functional expression here
+ if (context->expecting(Item::FUNC_ITEM) ||
+ func_item->functype() == Item_func::UNKNOWN_FUNC)
+ context->expect_nothing();
+ else
{
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(STRING_RESULT);
- context->expect_collation(item->collation.collation);
+ // Did not expect function here
+ context->supported= FALSE;
+ break;
}
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
- // Check that we are comparing with a field with same collation
- if (!context->expecting_collation(item->collation.collation))
- {
- DBUG_PRINT("info", ("Found non-matching collation %s",
- item->collation.collation->name));
- context->supported= FALSE;
- }
+
+ switch(func_item->functype()) {
+ case(Item_func::EQ_FUNC): {
+ DBUG_PRINT("info", ("EQ_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
}
- }
- else
- context->supported= FALSE;
- break;
- case(Item::INT_ITEM):
- DBUG_PRINT("info", ("INT_ITEM"));
- if (context->expecting(Item::INT_ITEM))
- {
- Item_int *int_item= (Item_int *) item;
- DBUG_PRINT("info", ("value %d", int_item->value));
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::INT_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(INT_RESULT);
+ case(Item_func::NE_FUNC): {
+ DBUG_PRINT("info", ("NE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
}
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
+ case(Item_func::LT_FUNC): {
+ DBUG_PRINT("info", ("LT_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::LE_FUNC): {
+ DBUG_PRINT("info", ("LE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::GE_FUNC): {
+ DBUG_PRINT("info", ("GE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::GT_FUNC): {
+ DBUG_PRINT("info", ("GT_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::REAL_ITEM);
+ context->expect(Item::DECIMAL_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::LIKE_FUNC): {
+ DBUG_PRINT("info", ("LIKE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::NOTLIKE_FUNC): {
+ DBUG_PRINT("info", ("NOTLIKE_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect(Item::FUNC_ITEM);
+ break;
+ }
+ case(Item_func::ISNULL_FUNC): {
+ DBUG_PRINT("info", ("ISNULL_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::ISNOTNULL_FUNC): {
+ DBUG_PRINT("info", ("ISNOTNULL_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::FIELD_ITEM);
+ context->expect_field_result(STRING_RESULT);
+ context->expect_field_result(REAL_RESULT);
+ context->expect_field_result(INT_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ break;
+ }
+ case(Item_func::NOT_FUNC): {
+ DBUG_PRINT("info", ("NOT_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(func_item->functype(),
+ func_item);
+ context->expect(Item::FUNC_ITEM);
context->expect(Item::COND_ITEM);
+ break;
}
- }
- else
- context->supported= FALSE;
- break;
- case(Item::REAL_ITEM):
- DBUG_PRINT("info", ("REAL_ITEM %s"));
- if (context->expecting(Item::REAL_ITEM))
- {
- Item_float *float_item= (Item_float *) item;
- DBUG_PRINT("info", ("value %f", float_item->value));
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::REAL_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
- {
- // We have not seen the field argument yet
+ case(Item_func::BETWEEN) : {
+ DBUG_PRINT("info", ("BETWEEN, rewriting using AND"));
+ Ndb_rewrite_context *rewrite_context=
+ new Ndb_rewrite_context(func_item);
+ rewrite_context->next= context->rewrite_stack;
+ context->rewrite_stack= rewrite_context;
+ DBUG_PRINT("info", ("COND_AND_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::COND_AND_FUNC,
+ func_item->argument_count() - 1);
context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(REAL_RESULT);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FUNC_ITEM);
+ break;
}
- else
- {
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
+ case(Item_func::IN_FUNC) : {
+ DBUG_PRINT("info", ("IN_FUNC, rewriting using OR"));
+ Ndb_rewrite_context *rewrite_context=
+ new Ndb_rewrite_context(func_item);
+ rewrite_context->next= context->rewrite_stack;
+ context->rewrite_stack= rewrite_context;
+ DBUG_PRINT("info", ("COND_OR_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(Item_func::COND_OR_FUNC,
+ func_item->argument_count() - 1);
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect(Item::INT_ITEM);
+ context->expect(Item::STRING_ITEM);
+ context->expect(Item::VARBIN_ITEM);
+ context->expect(Item::FUNC_ITEM);
+ break;
}
+ case(Item_func::UNKNOWN_FUNC): {
+ DBUG_PRINT("info", ("UNKNOWN_FUNC %s",
+ func_item->const_item()?"const":""));
+ DBUG_PRINT("info", ("result type %d", func_item->result_type()));
+ if (func_item->const_item())
+ switch(func_item->result_type()) {
+ case(STRING_RESULT): {
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::STRING_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(STRING_RESULT);
+ context->expect_collation(func_item->collation.collation);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ // Check that string result have correct collation
+ if (!context->expecting_collation(item->collation.collation))
+ {
+ DBUG_PRINT("info", ("Found non-matching collation %s",
+ item->collation.collation->name));
+ context->supported= FALSE;
+ }
+ }
+ // Skip any arguments since we will evaluate function instead
+ DBUG_PRINT("info", ("Skip until end of arguments marker"));
+ context->skip= func_item->argument_count();
+ break;
+ }
+ case(REAL_RESULT): {
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::REAL_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(REAL_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
+
+ // Skip any arguments since we will evaluate function instead
+ DBUG_PRINT("info", ("Skip until end of arguments marker"));
+ context->skip= func_item->argument_count();
+ break;
+ }
+ case(INT_RESULT): {
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::INT_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(INT_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
+
+ // Skip any arguments since we will evaluate function instead
+ DBUG_PRINT("info", ("Skip until end of arguments marker"));
+ context->skip= func_item->argument_count();
+ break;
+ }
+ case(DECIMAL_RESULT): {
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::DECIMAL_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(DECIMAL_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
+ // Skip any arguments since we will evaluate function instead
+ DBUG_PRINT("info", ("Skip until end of arguments marker"));
+ context->skip= func_item->argument_count();
+ break;
+ }
+ default:
+ break;
+ }
+ else
+ // Function does not return constant expression
+ context->supported= FALSE;
+ break;
+ }
+ default: {
+ DBUG_PRINT("info", ("Found func_item of type %d",
+ func_item->functype()));
+ context->supported= FALSE;
+ }
+ }
+ break;
}
- else
- context->supported= FALSE;
- break;
- case(Item::VARBIN_ITEM):
- DBUG_PRINT("info", ("VARBIN_ITEM"));
- if (context->expecting(Item::VARBIN_ITEM))
- {
+ case(Item::STRING_ITEM):
+ DBUG_PRINT("info", ("STRING_ITEM"));
+ if (context->expecting(Item::STRING_ITEM))
+ {
#ifndef DBUG_OFF
- char buff[256];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- str.length(0);
- Item_hex_string *varbin_item= (Item_hex_string *) item;
- DBUG_PRINT("info", ("value \"%s\"",
- varbin_item->val_str(&str)->ptr()));
+ char buff[256];
+ String str(buff,(uint32) sizeof(buff), system_charset_info);
+ str.length(0);
+ Item_string *string_item= (Item_string *) item;
+ DBUG_PRINT("info", ("value \"%s\"",
+ string_item->val_str(&str)->ptr()));
#endif
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::VARBIN_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::STRING_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(STRING_RESULT);
+ context->expect_collation(item->collation.collation);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ // Check that we are comparing with a field with same collation
+ if (!context->expecting_collation(item->collation.collation))
+ {
+ DBUG_PRINT("info", ("Found non-matching collation %s",
+ item->collation.collation->name));
+ context->supported= FALSE;
+ }
+ }
+ }
+ else
+ context->supported= FALSE;
+ break;
+ case(Item::INT_ITEM):
+ DBUG_PRINT("info", ("INT_ITEM"));
+ if (context->expecting(Item::INT_ITEM))
{
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(STRING_RESULT);
+ Item_int *int_item= (Item_int *) item;
+ DBUG_PRINT("info", ("value %d", int_item->value));
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::INT_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(INT_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
}
else
+ context->supported= FALSE;
+ break;
+ case(Item::REAL_ITEM):
+ DBUG_PRINT("info", ("REAL_ITEM %s"));
+ if (context->expecting(Item::REAL_ITEM))
{
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
+ Item_float *float_item= (Item_float *) item;
+ DBUG_PRINT("info", ("value %f", float_item->value));
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::REAL_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(REAL_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
}
- }
- else
- context->supported= FALSE;
- break;
- case(Item::DECIMAL_ITEM):
- DBUG_PRINT("info", ("DECIMAL_ITEM %s"));
- if (context->expecting(Item::DECIMAL_ITEM))
- {
- Item_decimal *decimal_item= (Item_decimal *) item;
- DBUG_PRINT("info", ("value %f", decimal_item->val_real()));
- NDB_ITEM_QUALIFICATION q;
- q.value_type= Item::DECIMAL_ITEM;
- curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
- if (context->expect_field_result_mask)
+ else
+ context->supported= FALSE;
+ break;
+ case(Item::VARBIN_ITEM):
+ DBUG_PRINT("info", ("VARBIN_ITEM"));
+ if (context->expecting(Item::VARBIN_ITEM))
{
- // We have not seen the field argument yet
- context->expect_only(Item::FIELD_ITEM);
- context->expect_only_field_result(REAL_RESULT);
- context->expect_field_result(DECIMAL_RESULT);
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::VARBIN_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(STRING_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
}
else
+ context->supported= FALSE;
+ break;
+ case(Item::DECIMAL_ITEM):
+ DBUG_PRINT("info", ("DECIMAL_ITEM %s"));
+ if (context->expecting(Item::DECIMAL_ITEM))
{
- // Expect another logical expression
- context->expect_only(Item::FUNC_ITEM);
- context->expect(Item::COND_ITEM);
+ Item_decimal *decimal_item= (Item_decimal *) item;
+ DBUG_PRINT("info", ("value %f", decimal_item->val_real()));
+ NDB_ITEM_QUALIFICATION q;
+ q.value_type= Item::DECIMAL_ITEM;
+ curr_cond->ndb_item= new Ndb_item(NDB_VALUE, q, item);
+ if (context->expect_field_result_mask)
+ {
+ // We have not seen the field argument yet
+ context->expect_only(Item::FIELD_ITEM);
+ context->expect_only_field_result(REAL_RESULT);
+ context->expect_field_result(DECIMAL_RESULT);
+ }
+ else
+ {
+ // Expect another logical expression
+ context->expect_only(Item::FUNC_ITEM);
+ context->expect(Item::COND_ITEM);
+ }
}
+ else
+ context->supported= FALSE;
+ break;
+ case(Item::COND_ITEM): {
+ Item_cond *cond_item= (Item_cond *) item;
+
+ if (context->expecting(Item::COND_ITEM))
+ switch(cond_item->functype()) {
+ case(Item_func::COND_AND_FUNC):
+ DBUG_PRINT("info", ("COND_AND_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
+ cond_item);
+ break;
+ case(Item_func::COND_OR_FUNC):
+ DBUG_PRINT("info", ("COND_OR_FUNC"));
+ curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
+ cond_item);
+ break;
+ default:
+ DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
+ context->supported= FALSE;
+ break;
+ }
+ else
+ // Did not expect condition
+ context->supported= FALSE;
+ break;
}
- else
+ default: {
+ DBUG_PRINT("info", ("Found item of type %d", item->type()));
context->supported= FALSE;
- break;
- case(Item::COND_ITEM): {
- Item_cond *cond_item= (Item_cond *) item;
-
- if (context->expecting(Item::COND_ITEM))
- switch(cond_item->functype()) {
- case(Item_func::COND_AND_FUNC):
- DBUG_PRINT("info", ("COND_AND_FUNC"));
- curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
- cond_item);
- break;
- case(Item_func::COND_OR_FUNC):
- DBUG_PRINT("info", ("COND_OR_FUNC"));
- curr_cond->ndb_item= new Ndb_item(cond_item->functype(),
- cond_item);
- break;
- default:
- DBUG_PRINT("info", ("COND_ITEM %d", cond_item->functype()));
- context->supported= FALSE;
- break;
- }
- else
- // Did not expect condition
- context->supported= FALSE;
- break;
- }
- default: {
- DBUG_PRINT("info", ("Found item of type %d", item->type()));
- context->supported= FALSE;
- }
+ }
+ }
+
+ if (context->supported && context->rewrite_stack)
+ {
+ Ndb_rewrite_context *rewrite_context= context->rewrite_stack;
+ if (rewrite_context->count ==
+ rewrite_context->func_item->argument_count())
+ {
+ // Rewrite is done, wrap an END() at the en
+ DBUG_PRINT("info", ("End of condition group"));
+ prev_cond= curr_cond;
+ curr_cond= context->cond_ptr= new Ndb_cond();
+ prev_cond->next= curr_cond;
+ curr_cond->ndb_item= new Ndb_item(NDB_END_COND);
+ // Pop rewrite stack
+ context->rewrite_stack= context->rewrite_stack->next;
+ }
}
+ }
}
-
+
DBUG_VOID_RETURN;
}
@@ -6925,8 +7131,10 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
break;
}
case(Item_func::NOT_FUNC): {
+ DBUG_PRINT("info", ("Generating negated query"));
cond= cond->next;
negated= TRUE;
+
break;
}
default:
@@ -6942,12 +7150,14 @@ ha_ndbcluster::build_scan_filter_group(Ndb_cond* &cond, NdbScanFilter *filter)
if (cond) cond= cond->next;
if (filter->end() == -1)
DBUG_RETURN(1);
- break;
+ if (!negated)
+ break;
+ // else fall through (NOT END is an illegal condition)
default: {
DBUG_PRINT("info", ("Illegal scan filter"));
}
}
- } while (level > 0);
+ } while (level > 0 || negated);
DBUG_RETURN(0);
}
@@ -6958,14 +7168,20 @@ ha_ndbcluster::build_scan_filter(Ndb_cond * &cond, NdbScanFilter *filter)
bool simple_cond= TRUE;
DBUG_ENTER("build_scan_filter");
- switch(cond->ndb_item->type) {
- case(Item_func::COND_AND_FUNC):
- case(Item_func::COND_OR_FUNC):
- simple_cond= FALSE;
- break;
- default:
- break;
- }
+ switch(cond->ndb_item->type) {
+ case(NDB_FUNCTION):
+ switch(cond->ndb_item->qualification.function_type) {
+ case(Item_func::COND_AND_FUNC):
+ case(Item_func::COND_OR_FUNC):
+ simple_cond= FALSE;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
if (simple_cond && filter->begin() == -1)
DBUG_RETURN(1);
if (build_scan_filter_group(cond, filter))
@@ -6983,6 +7199,7 @@ ha_ndbcluster::generate_scan_filter(Ndb_cond_stack *ndb_cond_stack,
DBUG_ENTER("generate_scan_filter");
if (ndb_cond_stack)
{
+ DBUG_PRINT("info", ("Generating scan filter"));
NdbScanFilter filter(op);
bool multiple_cond= FALSE;
// Wrap an AND group around multiple conditions
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 01e7bea057f..f73ca8a974e 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -86,6 +86,7 @@ typedef struct ndb_item_field_value {
typedef union ndb_item_value {
const Item *item;
NDB_ITEM_FIELD_VALUE *field_value;
+ uint arg_count;
} NDB_ITEM_VALUE;
struct negated_function_mapping
@@ -144,6 +145,7 @@ class Ndb_item {
}
case(NDB_FUNCTION):
value.item= item_value;
+ value.arg_count= ((Item_func *) item_value)->argument_count();
break;
case(NDB_END_COND):
break;
@@ -162,6 +164,13 @@ class Ndb_item {
{
qualification.function_type= func_type;
value.item= item_value;
+ value.arg_count= ((Item_func *) item_value)->argument_count();
+ };
+ Ndb_item(Item_func::Functype func_type, uint no_args)
+ : type(NDB_FUNCTION)
+ {
+ qualification.function_type= func_type;
+ value.arg_count= no_args;
};
~Ndb_item()
{
@@ -194,7 +203,7 @@ class Ndb_item {
int argument_count()
{
- return ((Item_func *) value.item)->argument_count();
+ return value.arg_count;
};
const char* get_val()
@@ -273,12 +282,28 @@ class Ndb_cond_stack
{
if (ndb_cond) delete ndb_cond;
ndb_cond= NULL;
+ if (next) delete next;
next= NULL;
};
Ndb_cond *ndb_cond;
Ndb_cond_stack *next;
};
+class Ndb_rewrite_context
+{
+public:
+ Ndb_rewrite_context(Item_func *func)
+ : func_item(func), left_hand_item(NULL), count(0) {};
+ ~Ndb_rewrite_context()
+ {
+ if (next) delete next;
+ }
+ const Item_func *func_item;
+ const Item *left_hand_item;
+ uint count;
+ Ndb_rewrite_context *next;
+};
+
/*
This class is used for storing the context when traversing
the Item tree. It stores a reference to the table the condition
@@ -292,11 +317,16 @@ class Ndb_cond_traverse_context
Ndb_cond_traverse_context(TABLE *tab, void* ndb_tab, Ndb_cond_stack* stack)
: table(tab), ndb_table(ndb_tab),
supported(TRUE), stack_ptr(stack), cond_ptr(NULL),
- expect_mask(0), expect_field_result_mask(0), skip(0), collation(NULL)
+ expect_mask(0), expect_field_result_mask(0), skip(0), collation(NULL),
+ rewrite_stack(NULL)
{
if (stack)
cond_ptr= stack->ndb_cond;
};
+ ~Ndb_cond_traverse_context()
+ {
+ if (rewrite_stack) delete rewrite_stack;
+ }
void expect(Item::Type type)
{
expect_mask|= (1 << type);
@@ -357,7 +387,7 @@ class Ndb_cond_traverse_context
uint expect_field_result_mask;
uint skip;
CHARSET_INFO* collation;
-
+ Ndb_rewrite_context *rewrite_stack;
};
/*
diff --git a/sql/item.cc b/sql/item.cc
index 913c01f5992..5fef75a6e30 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1027,7 +1027,7 @@ Item_field::Item_field(THD *thd, Field *f)
structure can go away and pop up again between subsequent executions
of a prepared statement).
*/
- if (thd->current_arena->is_stmt_prepare())
+ if (thd->current_arena->is_stmt_prepare_or_first_sp_execute())
{
if (db_name)
orig_db_name= thd->strdup(db_name);
diff --git a/sql/item.h b/sql/item.h
index f2e8e582780..4f5ed9934c5 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -585,10 +585,12 @@ public:
}
/* For error printing */
- inline void my_name(char **strp, uint *lengthp)
+ inline LEX_STRING *my_name(LEX_STRING *get_name)
{
- *strp= m_name.str;
- *lengthp= m_name.length;
+ if (!get_name)
+ return &m_name;
+ (*get_name)= m_name;
+ return get_name;
}
bool is_splocal() { return 1; } /* Needed for error checking */
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index a7abb5f9be8..3f25d473792 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1116,8 +1116,8 @@ Item_func_ifnull::fix_length_and_dec()
max_length= (max(args[0]->max_length - args[0]->decimals,
args[1]->max_length - args[1]->decimals) +
decimals);
- agg_result_type(&cached_result_type, args, 2);
- switch (cached_result_type) {
+ agg_result_type(&hybrid_type, args, 2);
+ switch (hybrid_type) {
case STRING_RESULT:
agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV);
break;
@@ -1155,7 +1155,7 @@ Field *Item_func_ifnull::tmp_table_field(TABLE *table)
}
double
-Item_func_ifnull::val_real()
+Item_func_ifnull::real_op()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val_real();
@@ -1171,7 +1171,7 @@ Item_func_ifnull::val_real()
}
longlong
-Item_func_ifnull::val_int()
+Item_func_ifnull::int_op()
{
DBUG_ASSERT(fixed == 1);
longlong value=args[0]->val_int();
@@ -1187,7 +1187,7 @@ Item_func_ifnull::val_int()
}
-my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
+my_decimal *Item_func_ifnull::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
my_decimal *value= args[0]->val_decimal(decimal_value);
@@ -1204,7 +1204,7 @@ my_decimal *Item_func_ifnull::val_decimal(my_decimal *decimal_value)
String *
-Item_func_ifnull::val_str(String *str)
+Item_func_ifnull::str_op(String *str)
{
DBUG_ASSERT(fixed == 1);
String *res =args[0]->val_str(str);
@@ -1227,9 +1227,16 @@ Item_func_if::fix_length_and_dec()
{
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
decimals= max(args[1]->decimals, args[2]->decimals);
- max_length= (max(args[1]->max_length - args[1]->decimals,
+ if (decimals == NOT_FIXED_DEC)
+ {
+ max_length= max(args[1]->max_length, args[2]->max_length);
+ }
+ else
+ {
+ max_length= (max(args[1]->max_length - args[1]->decimals,
args[2]->max_length - args[2]->decimals) +
decimals);
+ }
enum Item_result arg1_type=args[1]->result_type();
enum Item_result arg2_type=args[2]->result_type();
bool null1=args[1]->const_item() && args[1]->null_value;
@@ -1678,7 +1685,7 @@ void Item_func_case::print(String *str)
Coalesce - return first not NULL argument.
*/
-String *Item_func_coalesce::val_str(String *str)
+String *Item_func_coalesce::str_op(String *str)
{
DBUG_ASSERT(fixed == 1);
null_value=0;
@@ -1692,7 +1699,7 @@ String *Item_func_coalesce::val_str(String *str)
return 0;
}
-longlong Item_func_coalesce::val_int()
+longlong Item_func_coalesce::int_op()
{
DBUG_ASSERT(fixed == 1);
null_value=0;
@@ -1706,7 +1713,7 @@ longlong Item_func_coalesce::val_int()
return 0;
}
-double Item_func_coalesce::val_real()
+double Item_func_coalesce::real_op()
{
DBUG_ASSERT(fixed == 1);
null_value=0;
@@ -1721,7 +1728,7 @@ double Item_func_coalesce::val_real()
}
-my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
+my_decimal *Item_func_coalesce::decimal_op(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed == 1);
null_value= 0;
@@ -1738,8 +1745,8 @@ my_decimal *Item_func_coalesce::val_decimal(my_decimal *decimal_value)
void Item_func_coalesce::fix_length_and_dec()
{
- agg_result_type(&cached_result_type, args, arg_count);
- switch (cached_result_type) {
+ agg_result_type(&hybrid_type, args, arg_count);
+ switch (hybrid_type) {
case STRING_RESULT:
count_only_length();
decimals= NOT_FIXED_DEC;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index a929d509723..7a22e76b217 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -453,23 +453,19 @@ public:
};
-class Item_func_coalesce :public Item_func
+class Item_func_coalesce :public Item_func_numhybrid
{
protected:
- enum Item_result cached_result_type;
- Item_func_coalesce(Item *a, Item *b)
- :Item_func(a, b), cached_result_type(INT_RESULT)
- {}
+ Item_func_coalesce(Item *a, Item *b) :Item_func_numhybrid(a, b) {}
public:
- Item_func_coalesce(List<Item> &list)
- :Item_func(list),cached_result_type(INT_RESULT)
- {}
- double val_real();
- longlong val_int();
- String *val_str(String *);
- my_decimal *val_decimal(my_decimal *);
+ Item_func_coalesce(List<Item> &list) :Item_func_numhybrid(list) {}
+ double real_op();
+ longlong int_op();
+ String *str_op(String *);
+ my_decimal *decimal_op(my_decimal *);
void fix_length_and_dec();
- enum Item_result result_type () const { return cached_result_type; }
+ void find_num_type() {}
+ enum Item_result result_type () const { return hybrid_type; }
const char *func_name() const { return "coalesce"; }
table_map not_null_tables() const { return 0; }
};
@@ -482,10 +478,10 @@ protected:
bool field_type_defined;
public:
Item_func_ifnull(Item *a, Item *b) :Item_func_coalesce(a,b) {}
- double val_real();
- longlong val_int();
- String *val_str(String *str);
- my_decimal *val_decimal(my_decimal *);
+ double real_op();
+ longlong int_op();
+ String *str_op(String *str);
+ my_decimal *decimal_op(my_decimal *);
enum_field_types field_type() const;
void fix_length_and_dec();
const char *func_name() const { return "ifnull"; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 3767844e200..5af99cb8132 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -695,8 +695,8 @@ String *Item_int_func::val_str(String *str)
/*
- Check arguments here to determine result's type for function with two
- arguments.
+ Check arguments here to determine result's type for a numeric
+ function of two arguments.
SYNOPSIS
Item_num_op::find_num_type()
@@ -722,8 +722,9 @@ void Item_num_op::find_num_type(void)
hybrid_type= DECIMAL_RESULT;
result_precision();
}
- else if (r0 == INT_RESULT && r1 == INT_RESULT)
+ else
{
+ DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT);
decimals= 0;
hybrid_type=INT_RESULT;
result_precision();
@@ -738,7 +739,9 @@ void Item_num_op::find_num_type(void)
/*
- Set result type of function if it (type) is depends only on first argument
+ Set result type for a numeric function of one argument
+ (can be also used by a numeric function of many arguments, if the result
+ type depends only on the first argument)
SYNOPSIS
Item_func_num1::find_num_type()
@@ -817,6 +820,8 @@ String *Item_func_numhybrid::val_str(String *str)
str->set(nr,decimals,&my_charset_bin);
break;
}
+ case STRING_RESULT:
+ return str_op(&str_value);
default:
DBUG_ASSERT(0);
}
@@ -841,6 +846,14 @@ double Item_func_numhybrid::val_real()
return (double)int_op();
case REAL_RESULT:
return real_op();
+ case STRING_RESULT:
+ {
+ char *end_not_used;
+ int err_not_used;
+ String *res= str_op(&str_value);
+ return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
+ &end_not_used, &err_not_used) : 0.0);
+ }
default:
DBUG_ASSERT(0);
}
@@ -865,6 +878,15 @@ longlong Item_func_numhybrid::val_int()
return int_op();
case REAL_RESULT:
return (longlong)real_op();
+ case STRING_RESULT:
+ {
+ char *end_not_used;
+ int err_not_used;
+ String *res= str_op(&str_value);
+ CHARSET_INFO *cs= str_value.charset();
+ return (res ? (*(cs->cset->strtoll10))(cs, res->ptr(), &end_not_used,
+ &err_not_used) : 0);
+ }
default:
DBUG_ASSERT(0);
}
@@ -893,6 +915,12 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
break;
}
case STRING_RESULT:
+ {
+ String *res= str_op(&str_value);
+ str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
+ res->length(), res->charset(), decimal_value);
+ break;
+ }
case ROW_RESULT:
default:
DBUG_ASSERT(0);
@@ -2325,9 +2353,6 @@ longlong Item_func_field::val_int()
{
DBUG_ASSERT(fixed == 1);
- if (args[0]->is_null())
- return 0;
-
if (cmp_type == STRING_RESULT)
{
String *field;
@@ -2343,6 +2368,8 @@ longlong Item_func_field::val_int()
else if (cmp_type == INT_RESULT)
{
longlong val= args[0]->val_int();
+ if (args[0]->null_value)
+ return 0;
for (uint i=1; i < arg_count ; i++)
{
if (!args[i]->is_null() && val == args[i]->val_int())
@@ -2353,6 +2380,8 @@ longlong Item_func_field::val_int()
{
my_decimal dec_arg_buf, *dec_arg,
dec_buf, *dec= args[0]->val_decimal(&dec_buf);
+ if (args[0]->null_value)
+ return 0;
for (uint i=1; i < arg_count; i++)
{
dec_arg= args[i]->val_decimal(&dec_arg_buf);
@@ -2363,6 +2392,8 @@ longlong Item_func_field::val_int()
else
{
double val= args[0]->val_real();
+ if (args[0]->null_value)
+ return 0;
for (uint i=1; i < arg_count ; i++)
{
if (!args[i]->is_null() && val == args[i]->val_real())
@@ -4509,7 +4540,7 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
!my_strcasecmp(system_charset_info, name.str, "VERSION"))
return new Item_string("@@VERSION", server_version,
(uint) strlen(server_version),
- system_charset_info);
+ system_charset_info, DERIVATION_SYSCONST);
Item *item;
sys_var *var;
diff --git a/sql/item_func.h b/sql/item_func.h
index b53f2a0b9c6..f0c7e25ad53 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -189,10 +189,13 @@ class Item_func_numhybrid: public Item_func
protected:
Item_result hybrid_type;
public:
- Item_func_numhybrid(Item *a) :Item_func(a),hybrid_type(REAL_RESULT)
+ Item_func_numhybrid(Item *a) :Item_func(a), hybrid_type(REAL_RESULT)
{}
Item_func_numhybrid(Item *a,Item *b)
- :Item_func(a,b),hybrid_type(REAL_RESULT)
+ :Item_func(a,b), hybrid_type(REAL_RESULT)
+ {}
+ Item_func_numhybrid(List<Item> &list)
+ :Item_func(list), hybrid_type(REAL_RESULT)
{}
enum Item_result result_type () const { return hybrid_type; }
@@ -208,6 +211,7 @@ public:
virtual longlong int_op()= 0;
virtual double real_op()= 0;
virtual my_decimal *decimal_op(my_decimal *)= 0;
+ virtual String *str_op(String *)= 0;
bool is_null() { (void) val_real(); return null_value; }
};
@@ -220,6 +224,7 @@ public:
void fix_num_length_and_dec();
void find_num_type();
+ String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
};
@@ -231,6 +236,7 @@ class Item_num_op :public Item_func_numhybrid
virtual void result_precision()= 0;
void print(String *str) { print_op(str); }
void find_num_type();
+ String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index b7aefdd6f2e..4f1e5b9a290 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -362,7 +362,7 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
because we do not rollback this changes
TODO: make rollback for it, or special name resolving mode in 5.0.
*/
- !arena->is_stmt_prepare()
+ !arena->is_stmt_prepare_or_first_sp_execute()
)
{
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 0f2c9a2907d..76b0fa6afcf 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -499,7 +499,6 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
timestamp_type type, String *str)
{
char intbuff[15];
- uint days_i;
uint hours_i;
uint weekday;
ulong length;
@@ -602,8 +601,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
break;
case 'h':
case 'I':
- days_i= l_time->hour/24;
- hours_i= (l_time->hour%24 + 11)%12+1 + 24*days_i;
+ hours_i= (l_time->hour%24 + 11)%12+1;
length= int10_to_str(hours_i, intbuff, 10) - intbuff;
str->append_with_prefill(intbuff, length, 2, '0');
break;
@@ -624,8 +622,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
str->append_with_prefill(intbuff, length, 1, '0');
break;
case 'l':
- days_i= l_time->hour/24;
- hours_i= (l_time->hour%24 + 11)%12+1 + 24*days_i;
+ hours_i= (l_time->hour%24 + 11)%12+1;
length= int10_to_str(hours_i, intbuff, 10) - intbuff;
str->append_with_prefill(intbuff, length, 1, '0');
break;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 5f0db0bd2d5..0d743f99b73 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1715,7 +1715,8 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
Item_string *tmp;
pthread_mutex_lock(&LOCK_global_system_variables);
char *str= (char*) value_ptr(thd, var_type, base);
- tmp= new Item_string(str, strlen(str), system_charset_info);
+ tmp= new Item_string(str, strlen(str),
+ system_charset_info, DERIVATION_SYSCONST);
pthread_mutex_unlock(&LOCK_global_system_variables);
return tmp;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a07927547c6..f68a06a80e5 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3224,7 +3224,8 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
if (!(*leaves))
make_leaves_list(leaves, tables);
- for (TABLE_LIST *table_list= *leaves;
+ TABLE_LIST *table_list;
+ for (table_list= *leaves;
table_list;
table_list= table_list->next_leaf, tablenr++)
{
@@ -3263,7 +3264,7 @@ bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds,
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
DBUG_RETURN(1);
}
- for (TABLE_LIST *table_list= tables;
+ for (table_list= tables;
table_list;
table_list= table_list->next_local)
{
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index bd137e15b90..5e5bb1d8d3b 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -28,7 +28,7 @@ template <uint default_width> class Bitmap
uint32 buffer[(default_width+31)/32];
public:
Bitmap() { init(); }
- Bitmap(Bitmap& from) { *this=from; }
+ Bitmap(const Bitmap& from) { *this=from; }
explicit Bitmap(uint prefix_to_set) { init(prefix_to_set); }
void init() { bitmap_init(&map, buffer, default_width, 0); }
void init(uint prefix_to_set) { init(); set_prefix(prefix_to_set); }
@@ -61,19 +61,17 @@ public:
my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
char *print(char *buf) const
{
- char *s=buf; int i;
- uchar *uchar_buffer= (uchar*)&buffer;
- for (i=sizeof(buffer)-1; i>=0 ; i--)
+ char *s=buf;
+ const uchar *e=buffer, *b=e+sizeof(buffer)-1;
+ while (!*b && b>e)
+ b--;
+ if ((*s=_dig_vec_upper[*b >> 4]) != '0')
+ s++;
+ *s++=_dig_vec_upper[*b & 15];
+ while (--b>=e)
{
- if ((*s=_dig_vec_upper[uchar_buffer[i] >> 4]) != '0')
- break;
- if ((*s=_dig_vec_upper[uchar_buffer[i] & 15]) != '0')
- break;
- }
- for (s++, i-- ; i>=0 ; i--)
- {
- *s++=_dig_vec_upper[uchar_buffer[i] >> 4];
- *s++=_dig_vec_upper[uchar_buffer[i] & 15];
+ *s++=_dig_vec_upper[*b >> 4];
+ *s++=_dig_vec_upper[*b & 15];
}
*s=0;
return buf;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1a014e2151b..8f8ba9e2d8e 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -696,7 +696,8 @@ public:
virtual Type type() const;
virtual ~Item_arena() {};
- inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; }
+ inline bool is_stmt_prepare_or_first_sp_execute() const
+ { return (int)state < (int)PREPARED; }
inline bool is_first_stmt_execute() const { return state == PREPARED; }
inline bool is_stmt_execute() const
{ return state == PREPARED || state == EXECUTED; }
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 3947ed2ba27..c374890c717 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5898,7 +5898,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->db= empty_c_string;
ptr->db_length= 0;
}
- if (thd->current_arena->is_stmt_prepare())
+ if (thd->current_arena->is_stmt_prepare_or_first_sp_execute())
ptr->db= thd->strdup(ptr->db);
ptr->alias= alias_str;
@@ -6976,7 +6976,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
against the opened tables to ensure we don't use a table that is part
of the view (which can only be done after the table has been opened).
*/
- if (thd->current_arena->is_stmt_prepare())
+ if (thd->current_arena->is_stmt_prepare_or_first_sp_execute())
{
/*
For temporary tables we don't have to check if the created table exists
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 403d20f3ddb..5e8b6cb49e9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -5217,7 +5217,10 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
tmp= new Item_func_trig_cond(tmp, &tab->found);
}
if (tmp)
+ {
tmp->quick_fix_field();
+ tmp->update_used_tables();
+ }
return tmp;
}
@@ -5445,11 +5448,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
DBUG_RETURN(1);
tab->select_cond=sel->cond=tmp;
+ /* Push condition to storage engine if this is enabled
+ and the condition is not guarded */
+ tab->table->file->pushed_cond= NULL;
if (thd->variables.engine_condition_pushdown)
{
COND *push_cond=
- make_cond_for_table(cond,current_map,current_map);
- tab->table->file->pushed_cond= NULL;
+ make_cond_for_table(tmp, current_map, current_map);
if (push_cond)
{
/* Push condition to handler */
@@ -5790,6 +5795,7 @@ make_join_readinfo(JOIN *join, uint options)
if (!table->no_keyread)
{
if (tab->select && tab->select->quick &&
+ tab->select->quick->index != MAX_KEY && //not index_merge
table->used_keys.is_set(tab->select->quick->index))
{
table->key_read=1;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 8d36889df76..56401ced67c 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -323,7 +323,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
if (tmp_arena)
thd->restore_backup_item_arena(tmp_arena, &backup);
- if (arena->is_stmt_prepare())
+ if (arena->is_stmt_prepare_or_first_sp_execute())
{
/* prepare fake select to initialize it correctly */
init_prepare_fake_select_lex(thd);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a6e77edaa84..2a7237c7fc2 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4346,11 +4346,11 @@ simple_expr:
{
if ($3->is_splocal())
{
- LEX_STRING name;
+ LEX_STRING *name;
Item_splocal *il= static_cast<Item_splocal *>($3);
- il->my_name(&name.str, &name.length);
- my_error(ER_WRONG_COLUMN_NAME, MYF(0), name.str);
+ name= il->my_name(NULL);
+ my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
YYABORT;
}
$$= new Item_default_value($3);
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 9a8ee44c54c..002076afd90 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -7455,12 +7455,16 @@ static void test_explain_bug()
verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
"", "", "", NAME_LEN, 0);
- verify_prepare_field(result, 6, "key_len", "",
- (mysql_get_server_version(mysql) <= 50000 ?
- MYSQL_TYPE_LONGLONG : MYSQL_TYPE_VAR_STRING),
- "", "", "",
- (mysql_get_server_version(mysql) <= 50000 ? 3 : 4096),
- 0);
+ if (mysql_get_server_version(mysql) <= 50000)
+ {
+ verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
+ "", "", 3, 0);
+ }
+ else
+ {
+ verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
+ "", "", NAME_LEN*MAX_KEY, 0);
+ }
verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
"", "", "", NAME_LEN*16, 0);